systemMenu_REDの追加。(まだまともに動かない。)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@72 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yosiokat 2007-10-29 11:02:25 +00:00
parent 9774cca464
commit 1952c74fb3
120 changed files with 28779 additions and 1 deletions

View File

@ -24,7 +24,6 @@ include $(TWLFIRM_ROOT)/build/buildtools/commondefs
SUBDIRS = \
tools \
libraries \
norfirm \
nandfirm \
nand_formatter \

View File

@ -0,0 +1,95 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - commondefs - common definitions for build system
# File: commondefs
#
# 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:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_SYSMENU_COMMONDEFS_
TWL_SYSMENU_COMMONDEFS_ = TRUE
NITRO_NO_STD_PCHDR = TRUE # プリコンパイルヘッダ抑止
EMPTY ?=
SPACE ?= $(EMPTY) $(EMPTY)
#----------------------------------------------------------------------------
# TWL-SYSTEM-MENU path settings
#
SYSMENU_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(TWLIPL_ROOT)))
SYSMENU_BUILDTOOLSDIR := $(SYSMENU_ROOT)/build/buildtools
SYSMENU_INCDIR := $(SYSMENU_ROOT)/include
SYSMENU_TOOLSDIR := $(SYSMENU_ROOT)/tools
SYSMENU_COMPONENTSDIR := $(SYSMENU_ROOT)/components
LDEPENDS_LCF += $(SYSMENU_BUILDTOOLSDIR)/commondefs.sysmenu
LDEPENDS_RES += $(SYSMENU_BUILDTOOLSDIR)/commondefs.sysmenu
#----------------------------------------------------------------------------
### TWL-commondefs
#
#include $(TWLSDK_ROOT)/build/buildtools/commondefs
include $(NITROSYSTEM_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
### SYSTEM_MENU Library settings
SYSMENU_LIBDIR := $(SYSMENU_ROOT)/lib/$(TWL_LIBTYPE)
ifeq ($(CODEGEN_PROC),ARM9)
SYSMENU_LIBS ?= \
libsysmenu$(TWL_LIBSUFFIX).a \
libmbloader$(TWL_LIBSUFFIX).a \
libacsign$(TWL_LIBSUFFIX).a
else # ($(CODEGEN_PROC),ARM7)
SYSMENU_LIBS ?= \
libmbloader_sp$(TWL_LIBSUFFIX).a
endif
#----------------------------------------------------------------------------
# MY BUILD TOOLS
#
OPENSSL := $(SYSMENU_TOOLSDIR)/openssl/openssl.exe
MAKESYSMENU_RSA_PRVKEY ?= $(SYSMENU_TOOLSDIR)/openssl/rsa_private.der
MAKESYSMENU_RSA_PUBKEY ?= $(SYSMENU_TOOLSDIR)/openssl/rsa_public.der
#----------------------------------------------------------------------------
### Global Library resettings
GINCLUDES := $(SYSMENU_INCDIR) $(GINCLUDES)
GLIBRARY_DIRS := $(SYSMENU_LIBDIR) $(GLIBRARY_DIRS)
GLIBRARIES := $(SYSMENU_LIBS) $(GLIBRARIES)
#----------------------------------------------------------------------------
# TWLSYSMENU_INSTALL_ROOT
#
SYSMENU_INSTALL_ROOT := $(SYSMENU_ROOT)
SYSMENU_INSTALL_INCDIR := $(SYSMENU_INSTALL_ROOT)/include
SYSMENU_INSTALL_TOOLSDIR := $(SYSMENU_INSTALL_ROOT)/tools
SYSMENU_INSTALL_LIBDIR := $(SYSMENU_INSTALL_ROOT)/lib/$(TWL_LIBTYPE)
SYSMENU_INSTALL_COMPONENTSDIR := $(SYSMENU_INSTALL_ROOT)/components
#----------------------------------------------------------------------------
endif # TWL_SYSMENU_COMMONDEFS_
#----- End of commondefs -----

View File

@ -0,0 +1,30 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - modulerules - common rules for build system
# File: modulerules
#
# 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:: 2007-09-06$
# $Rev$
# $Author$
#----------------------------------------------------------------------------
ifndef TWL_SYSMENU_MODULERULES_
#----------------------------------------------------------------------------
### TWL-modulerules
#
#include $(TWLSDK_ROOT)/build/buildtools/modulerules
include $(NITROSYSTEM_ROOT)/build/buildtools/modulerules
#----------------------------------------------------------------------------
TWL_SYSMENU_MODULERULES_ = TRUE
endif # TWL_SYSMENU_MODULERULES_
#----- End of modulerules -----

View File

@ -0,0 +1,30 @@
#! 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:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
#----------------------------------------------------------------------------
SUBDIRS = sysmenu mb_loader acsign
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,56 @@
#! 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:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
INCDIR = include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SRCS = acsign.c acmemory.c acsign_util.c
TARGET_LIB = libacsign$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
CCFLAGS += -DSMALL_CODE_SIZE \
-DSTANDALONE \
-DOPT_32_BIT \
-DNO_SPLIT \
-DNO_FP_API \
-DNO_R_DIAG \
-DNO_STDIO_H \
-DNO_STDLIB_H
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: acmemory.h
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$
*---------------------------------------------------------------------------*/
#ifndef _ACMEMORY_H_
#define _ACMEMORY_H_
#ifdef __cplusplus
extern "C" {
#endif
//
void ACMemory_Clear( );
void* ACMemory_Alloc( u32 size );
void ACMemory_Free( void* adrs );
void* ACMemory_Memset( void* adrs, u32 val, u32 cnt );
void* ACMemory_Memcpy( void* dst, void* src, u32 cnt );
#ifdef __cplusplus
}
#endif
#endif //_ACMEMORY_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,356 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_BN_LCL_H
#define HEADER_COMMON_BN_LCL_H
#ifdef __cplusplus
extern "C" {
#endif
#if 0 //RSA
#include <stdio.h>
#include <stdlib.h>
#include "r_error.h"
#include "err.h"
#include <string.h>
#else //NITRO
#include "r_error.h"
#ifndef NULL
#define NULL 0
#endif
#endif
#ifndef STANDALONE
#include "r_com.h"
#else
#if 0 //RSA
#define NO_STDLIB_MAPPING
#define Malloc(a) malloc(a)
#define Free(a) free(a)
#define Memset(a,b,c) memset(a,b,c)
#define Memcpy(a,b,c) memcpy(a,b,c)
#else // Nitro
#define NO_STDLIB_MAPPING
#include "acmemory.h"
#define Malloc(a) ACMemory_Alloc(a)
#define Free(a) ACMemory_Free(a)
#define Memset(a,b,c) ACMemory_Memset(a,b,c)
#define Memcpy(a,b,c) ACMemory_Memcpy(a,b,c)
#endif
#endif
/* TEMP FIX */
#undef BNerr
#define BNerr(a,b)
#include "bn.h"
#define BN_EXP_TABLE_SIZE 16
/* see the bn_limit_ fields which are the start of a runtime
* tunable set of values to match these fixed compile-time constants
*/
/* Pentium pro 16,16,16,32,64 */
/* Alpha 16,16,16,16.64 */
/* StrongARM */
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 */ /* less than */
#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
/*************************************************************
* Using the long long type
*/
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
/* These are used for internal error checking and are not normally used */
#ifdef BN_DEBUG
#define bn_check_top(a) \
{ if ( ((a)->top < 0) || \
((a)->top > (a)->max) || \
(((a)->top == 0) && (a)->neg) || \
(((a)->top == 1) && (a->d[0] == 0))) \
{ char *nullp=NULL; *nullp='z'; } }
#define bn_check_num(a) if ((a) < 0) { char *nullp=NULL; *nullp='z'; }
#define bn_assert(a) if (!(a)) { char *nullp=NULL; *nullp='z'; }
#define bn_set_used_check(l,size,num) bn_su_check(l,size,num)
#ifdef BN_DEBUG2
#define bn_do_used_check(fp,str,l,size,num) bn_du_check(fp,str,l,size,num)
#else
#define bn_do_used_check(fp,str,l,size,num)
#endif
#else
#define bn_assert(a)
#define bn_check_top(a)
#define bn_check_num(a)
#define bn_set_used_check(l,size,num)
#define bn_do_used_check(fp,str,l,size,num)
#endif
/***********************************************
* IA64 32 bit build SWIZZLE code
* This essentially casts our points which are
* 32bits under abi32 to 64bit unsigned long
* longs and then grabs the top two bits of the
* pointer and places it in the 2nd and 3rd bits
* of the unsigned long long.
**********************************************/
#ifdef HPUX_IA64_32
#define SWIZLLE(VALUE) ((((unsigned long long)(VALUE) & 0xc0000000LL) <<31)\
|((unsigned long long)(VALUE)))
#else
#define SWIZZLE(VALUE) (VALUE)
#endif
#define bn_neg_words(a,n) \
{ \
int iii; \
\
for (iii=0; iii<n; iii++) \
{ \
a[iii]= (-a[iii])&BN_MASK2; \
} \
for (;;) \
if ((++a[iii])&BN_MASK2) break; \
}
/* This macro is to add extra stuff for development checking */
#ifdef BN_DEBUG
#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
#else
#define bn_set_max(r)
#endif
/* These macros are used to 'take' a section of a bignum for read only use */
#define bn_set_low(r,a,n) \
{ \
(r)->top=((a)->top > (n))?(n):(a)->top; \
(r)->d=(a)->d; \
(r)->neg=(a)->neg; \
(r)->flags|=BN_FLG_STATIC_DATA; \
bn_set_max(r); \
}
#define bn_set_high(r,a,n) \
{ \
if ((a)->top > (n)) \
{ \
(r)->top=(a)->top-n; \
(r)->d= &((a)->d[n]); \
} \
else \
(r)->top=0; \
(r)->neg=(a)->neg; \
(r)->flags|=BN_FLG_STATIC_DATA; \
bn_set_max(r); \
}
/* #define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) */
#ifdef BN_LLONG
#define mul_add(r,a,w,c) { \
BN_ULLONG t; \
t=(BN_ULLONG)w * (a) + (r) + (c); \
(r)= Lw(t); \
(c)= Hw(t); \
}
#define mul(r,a,w,c) { \
BN_ULLONG t; \
t=(BN_ULLONG)w * (a) + (c); \
(r)= Lw(t); \
(c)= Hw(t); \
}
#else
/*************************************************************
* No long long type
*/
#define LBITS(a) ((a)&BN_MASK2l)
#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2lh)
#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2lh)<<BN_BITS4)
#define mul64(l,h,bl,bh) \
{ \
BN_ULONG m,m1,lt,ht; \
\
lt=l; \
ht=h; \
m =(bh)*(lt); \
lt=(bl)*(lt); \
m1=(bl)*(ht); \
ht =(bh)*(ht); \
m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
ht+=HBITS(m); \
m1=L2HBITS(m); \
lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
(l)=lt; \
(h)=ht; \
}
#define sqr64(lo,ho,in) \
{ \
BN_ULONG l,h,m; \
\
h=(in); \
l=LBITS(h); \
h=HBITS(h); \
m =(l)*(h); \
l*=l; \
h*=h; \
h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
m =((m&BN_MASK2l)<<(BN_BITS4+1))&BN_MASK2; \
l=(l+m)&BN_MASK2; if (l < m) h++; \
(lo)=l; \
(ho)=h; \
}
#if 0
#define mul_add(r,a,bl,bh,b_hl,c) { \
BN_ULONG l,h; \
BN_ULONG lt,mt; \
\
h= (a); \
l=LBITS(h); \
h=HBITS(h); \
mt=bl*l; \
lt=mt+c+(r); \
c=bh*h; \
mt+=c+(l-h)*b_hl; \
mt+=(lt>>BN_BITS4); \
(r)=(lt&BN_MASK2l)|((mt&BN_MASK2l)<<BN_BITS4); \
c+=(mt>>BN_BITS4); \
}
#else /* Normal version */
#define mul_add(r,a,bl,bh,b_hl,c) { \
BN_ULONG l,h; \
\
h= (a); \
l=LBITS(h); \
h=HBITS(h); \
mul64(l,h,(bl),(bh)); \
\
/* non-multiply part */ \
l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
(c)=(r); \
l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
(c)=h&BN_MASK2; \
(r)=l; \
}
#endif
#define mul(r,a,bl,bh,c) { \
BN_ULONG l,h; \
\
h= (a); \
l=LBITS(h); \
h=HBITS(h); \
mul64(l,h,(bl),(bh)); \
\
/* non-multiply part */ \
l+=(c); if ((l&BN_MASK2) < (c)) h++; \
(c)=h&BN_MASK2; \
(r)=l&BN_MASK2; \
}
#endif
#ifndef BN_MUL_COMBA
#define bn_mul_comba4(r,a,b) bn_mul_normal(r,a,4,b,4)
#define bn_mul_comba5(r,a,b) bn_mul_normal(r,a,5,b,5)
#define bn_mul_comba6(r,a,b) bn_mul_normal(r,a,6,b,6)
#define bn_mul_comba8(r,a,b) bn_mul_normal(r,a,8,b,8)
#define bn_mul_comba11(r,a,b) bn_mul_normal(r,a,11,b,11)
#define bn_mul_comba12(r,a,b) bn_mul_normal(r,a,12,b,12)
#define bn_mul_comba16(r,a,b) bn_mul_normal(r,a,16,b,16)
#endif
#if 1
#ifndef BN_SQR_COMBA
#define bn_sqr_comba4(r,a) bn_mul_normal(r,a,4,a,4)
#define bn_sqr_comba5(r,a) bn_mul_normal(r,a,5,a,5)
#define bn_sqr_comba6(r,a) bn_mul_normal(r,a,6,a,6)
#define bn_sqr_comba8(r,a) bn_mul_normal(r,a,8,a,8)
#define bn_sqr_comba11(r,a) bn_mul_normal(r,a,11,a,11)
#define bn_sqr_comba12(r,a) bn_mul_normal(r,a,12,a,12)
#define bn_sqr_comba16(r,a) bn_mul_normal(r,a,16,a,16)
#endif
#else
#ifndef BN_SQR_COMBA
#define bn_sqr_comba4(r,a) bn_mul_comba4(r,a,a)
#define bn_sqr_comba5(r,a) bn_mul_comba5(r,a,a)
#define bn_sqr_comba6(r,a) bn_mul_comba6(r,a,a)
#define bn_sqr_comba8(r,a) bn_mul_comba8(r,a,a)
#define bn_sqr_comba11(r,a) bn_mul_comba11(r,a,a)
#define bn_sqr_comba12(r,a) bn_mul_comba12(r,a,a)
#define bn_sqr_comba16(r,a) bn_mul_comba16(r,a,a)
#endif
#endif
#ifndef BN_REDUCE_COMBA
#define r0_bn_mont_comba4(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba5(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba6(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba8(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba11(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba12(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#define r0_bn_mont_comba16(r,a,n,num,n0) bn_from_montgomery_words(r,a,n,num,n0)
#endif
#ifndef NOPROTO
BIGNUM *bn_expand2(BIGNUM *b, int bits);
#ifdef X86_ASM
void bn_add_words(BN_ULONG *r,BN_ULONG *a,int num);
#endif
#else
BIGNUM *bn_expand2();
#ifdef X86_ASM
BN_ULONG bn_add_words();
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_BN_LCL_H */
void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2, BN_ULONG *t);
int BN_gen_exp_string(unsigned char *str, BIGNUM *p, int bits);
void bn_from_montgomery_rec_full(BN_ULONG *rp, BN_ULONG *ap,
BN_ULONG *np, BN_ULONG *nip, BN_ULONG *tmp,BN_REC *rec);
int bn_mont_ctx_new_word(const BN_ME_METH *meth, BN_ME_CTX **retp);

View File

@ -0,0 +1,317 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/*****************************************************************************
* Copyright (c). 2001 RSA Security Inc. All rights reserved.
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
****************************************************************************/
/**
* @file bn_thx.h
* @brief header file created for used as interface defines for systems
* containing hetergeneous environments where some bn operations
* will be performed in isolation from the rest of the library
*/
#ifndef HEADER_COMMON_BN_THX_H
#define HEADER_COMMON_BN_THX_H
#ifdef __cplusplus
extern "C" {
#endif
/* These defines are required on systems so that the mod_exp code
* to be used in isolation from the bn operation with library will work,
* if these are not available, the header files with equivalent functionality
* should be added inside a CPU or Operating system define
*/
#ifndef NO_STDIO_H
#include <stdio.h>
#endif
#ifndef NO_STDLIB_H
#include <stdlib.h>
#endif
#ifndef NO_STRING_H
#include <string.h>
#endif
/* Interface for ARM/DSP systems, this interface requires only
* the standard defines and includes at the moment
*/
#ifdef CPU_TMS320
#define THX_RECIPIENT
#define CPU_DSP
#endif
#ifdef THX_RECIPIENT
#ifndef restrict
#define restrict
#endif
#ifndef Malloc
#define Malloc malloc
#endif
#ifndef Memcpy
#define Memcpy memcpy
#endif
#ifndef Memmove
#define Memmove memmove
#endif
#ifndef Memset
#define Memset memset
#endif
#ifndef Free
#define Free free
#endif
#endif /* THX_RECIPIENT */
#ifndef THX_RECIPIENT /* not the recipient, we must be the caller */
#include "bn_lcl.h"
#endif /* ! THX_RECIPIENT */
/* The follow define protected inclusions are excerpts from the
* header file bn.h, this has been done, so that code written for the
* THX systems can be used in isolation from the library
* This code may need to be updated in line with changes to the bn.h
* header file.
*/
#ifndef HEADER_COMMON_BN_H
#define HEADER_COMMON_BN_H
#if !defined(CCONV)
#define CCONV
#endif
#ifndef PRE_CCONV
#define PRE_CCONV
#endif
/* convert from the new to the old option names */
#if defined(OPT_BN_LLONG)
#define BN_LLONG /* comment to make sure Configure leaves this alone */
#endif
#if defined(OPT_32_BIT_INT) || defined(OPT_32_BIT)
#define THIRTY_TWO_BIT
#endif
#define BN_ILONG BN_ULONG
#ifdef THIRTY_TWO_BIT
#define BN_ULLONG unsigned long long
#ifdef OPT_32_BIT_INT
#define BN_ULONG unsigned int
#define BN_LONG int
#else
#define BN_ULONG unsigned long
#define BN_LONG long
#endif
#define BN_BITS 64
#define BN_BYTES 4
#define BN_BITS2 32
#define BN_BITS4 16
/* This is needed because the Watcom compiler pre-processor
* under QNX is perverted and tries to parses the 'LL'
* part even though it is never used.
*/
#ifdef BN_LLONG
#define BN_MASK (0xffffffffffffffffL)
#endif
#define BN_MASK2 (0xffffffffL)
#define BN_MASK2l (0xffff)
#define BN_MASK2lh (0xffff)
#define BN_MASK2h1 (0xffff8000L)
#define BN_MASK2h (0xffff0000L)
#define BN_TBIT (0x80000000L)
#define BN_DEC_CONV (1000000000L)
#define BN_DEC_FMT1 "%lu"
#define BN_DEC_FMT2 "%09lu"
#define BN_DEC_NUM 9
#define BN_HEX_FMT "%08lX"
#endif
#define BN_EXP_TABLE_SIZE 16
typedef struct bignum_st BIGNUM;
struct bignum_st
{
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int max; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
PRE_CCONV BN_ULONG CCONV bn_mul_add_words(BN_ULONG *rp,BN_ULONG *ap,
int num, BN_ULONG w);
PRE_CCONV BN_ULONG CCONV bn_mul_words(BN_ULONG *rp, BN_ULONG *ap,
int num, BN_ULONG w);
PRE_CCONV void CCONV bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
BN_ULONG CCONV bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
PRE_CCONV BN_ULONG CCONV bn_add_words(BN_ULONG *rp, BN_ULONG *ap,
BN_ULONG *bp,int num);
PRE_CCONV BN_ULONG CCONV bn_sub_words(BN_ULONG *rp, BN_ULONG *ap,
BN_ULONG *bp,int num);
#ifndef BN_ME_METH
#define BN_ME_METH void
#endif
#endif /* ! HEADER_COMMON_BN_H */
/* The follow define protected inclusions are excerpts from the
* header file r_error.h, this has been done, so that code written for the
* THX systems can be used in isolation from the library
* This code may need to be updated in line with changes to the r_error.h
* header file.
*/
#ifndef HEADER_COMMON_R_ERROR_H
#define HEADER_COMMON_R_ERROR_H
/* The FATAL_INTERNAL_ERROR is a flag that is set with the following
* error codes:
* R_ERROR_INVALID_STATE
* R_ERROR_INIT_NOT_CALLED
* R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED
*/
#define R_ERROR_FATAL_INTERNAL_ERROR 64
/* The BAD_PARAMETER is a flag that is set with the following error
* codes:
* R_ERROR_NULL_ARG
* R_ERROR_BUFFER_TOO_SMALL
* R_ERROR_BAD_VALUE
* R_ERROR_BAD_RANGE
* R_ERROR_BAD_FORMAT
* R_ERROR_BAD_TYPE
* R_ERROR_BAD_DATA
* R_ERROR_BAD_LENGTH
*/
#define R_ERROR_BAD_PARAMETER 32
/* Base value for all general errors used through all products */
#define R_ERROR_BASE 10000
#define R_ERROR_NONE 0
#define R_ERROR_FAILED (R_ERROR_BASE+1)
#define R_ERROR_IO (R_ERROR_BASE+2)
#define R_ERROR_PROTOCOL (R_ERROR_BASE+3)
#define R_ERROR_EOF (R_ERROR_BASE+4)
#define R_ERROR_ALLOC_FAILURE (R_ERROR_BASE+5)
#define R_ERROR_EVAL_RESTRICTION (R_ERROR_BASE+6)
#define R_ERROR_EVAL_EXPIRED (R_ERROR_BASE+7)
#define R_ERROR_NOT_FOUND (R_ERROR_BASE+8)
#define R_ERROR_NOT_AVAILABLE (R_ERROR_BASE+9)
#define R_ERROR_NOT_IMPLEMENTED (R_ERROR_BASE+10)
#define R_ERROR_NOT_SUPPORTED (R_ERROR_BASE+11)
#define R_ERROR_INVALID_STATE \
((R_ERROR_BASE+12) | R_ERROR_FATAL_INTERNAL_ERROR)
#define R_ERROR_INIT_NOT_CALLED \
((R_ERROR_BASE+13) | R_ERROR_FATAL_INTERNAL_ERROR)
#define R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED \
((R_ERROR_BASE+14) | R_ERROR_FATAL_INTERNAL_ERROR)
#define R_ERROR_METHOD_UNDEFINED \
((R_ERROR_BASE+15) | R_ERROR_FATAL_INTERNAL_ERROR)
#define R_ERROR_BUFFER_TOO_SMALL \
((R_ERROR_BASE+16) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_NULL_ARG ((R_ERROR_BASE+17) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_VALUE ((R_ERROR_BASE+18) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_RANGE ((R_ERROR_BASE+19) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_FORMAT ((R_ERROR_BASE+20) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_TYPE ((R_ERROR_BASE+21) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_DATA ((R_ERROR_BASE+22) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_BAD_LENGTH ((R_ERROR_BASE+23) | R_ERROR_BAD_PARAMETER)
#define R_ERROR_RCOM_LIBRARY_NOT_SUPPORTED (R_ERROR_BASE+24)
/* Resource Manager base for errors */
#define R_COM_ERR_LIB_CTX_BASE 10100
#endif /* HEADER_COMMON_R_ERROR_H */
const BN_ME_METH *BN_ME_METH_thxc(void);
/**
* @note THX code only needs to store rr, n0, str
*
*/
typedef struct thxc_mont_ctx_st
{
BIGNUM *rr;
unsigned char *str;
unsigned int str_len;
BN_ULONG n0;
} THXC_MONT_CTX;
int Rx_thxr_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np,
BN_ULONG *rrp, BN_ULONG n0, int top, int tmp_len, unsigned char *str);
int Ri_thxr_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np,
BN_ULONG *rrp, BN_ULONG *dp, BN_ULONG *aap, BN_ULONG *rp, BN_ULONG *tmp,
BN_ULONG n0, int top, unsigned char *str);
void Ri_thxr_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
void Ri_thxr_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
void Ri_thxr_from_montgomery_words(BN_ULONG *ret,BN_ULONG *ap,BN_ULONG *np,
int w, BN_ULONG n0);
BN_ULONG Ri_thxr_from_mont_words(BN_ULONG *ap,BN_ULONG *wap,
BN_ULONG *np, int w, BN_ULONG n0);
#ifdef CPU_TMS320
/* Method and functions required for the ARM/DSP interface */
const BN_ME_METH *BN_ME_METH_dspc(void);
int Rx_dsp_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np,
BN_ULONG *rrp, BN_ULONG n0, int top, int tmp_len, unsigned char *str);
int Ri_dsp_mod_exp_mont( BN_ULONG *result, BN_ULONG *ap, BN_ULONG *np,
BN_ULONG *rrp, BN_ULONG *dp, BN_ULONG *aap, BN_ULONG *rp, BN_ULONG *tmp,
BN_ULONG n0, int top, unsigned char *str);
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_BN_THX_H */

View File

@ -0,0 +1,73 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
#ifndef _MD5_H_
#define _MD5_H_
#ifdef __cplusplus
extern "C" {
#endif
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
typedef struct MD5_CTX MD5_CTX;
typedef struct MD5_CTX MD5Context;
/* MD5 context. */
struct MD5_CTX{
unsigned long state[4]; /* state (ABCD) */
unsigned long count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} ;
void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char digest[16], MD5_CTX *);
#if defined( MD5_TEST )
int MD5Test( );
#endif // MD5_TEST
#ifdef __cplusplus
}
#endif
#endif // _MD5_H_

View File

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file r_error.h
* This file contains the error definitions for the toolkit.
*/
#ifndef HEADER_COMMON_R_ERROR_H
#define HEADER_COMMON_R_ERROR_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup R_ERROR_IDS Error Identifiers
* This section outlines the error codes returned, enabling identification of
* specific errors. For more information, see the
* <a href="pdf/dev_guide.pdf">Developer's Guide</a>.
*
* @{
*/
/**
* Indicates that a fatal error has occurred in the operation performed.
* This flag is set with the following error codes:<br>
* <ul>
* <li>#R_ERROR_INVALID_STATE.</li>
* <li>#R_ERROR_INIT_NOT_CALLED.</li>
* <li>#R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED.</li>
* </ul>
*/
#define R_ERROR_FATAL_INTERNAL_ERROR 64
/**
* Indicates that the specified parameter is incorrect or contains invalid
* information. This flag is set with the following error codes:<br>
* <ul>
* <li>#R_ERROR_NULL_ARG.</li>
* <li>#R_ERROR_BUFFER_TOO_SMALL.</li>
* <li>#R_ERROR_BAD_VALUE.</li>
* <li>#R_ERROR_BAD_RANGE.</li>
* <li>#R_ERROR_BAD_FORMAT.</li>
* <li>#R_ERROR_BAD_TYPE.</li>
* <li>#R_ERROR_BAD_DATA.</li>
* <li>#R_ERROR_BAD_LENGTH.</li>
* </ul>
*/
#define R_ERROR_BAD_PARAMETER 32
/* Indicates the base value for all general errors used through all products */
#define R_ERROR_BASE 10000
/**
* Indicates that no errors were detected in the requested operation.
*/
#define R_ERROR_NONE 0
/**
* Indicates that the requested operation failed.
*/
#define R_ERROR_FAILED (R_ERROR_BASE+1)
/**
* Indicates that the requested operation detected an Input/Output error.
*/
#define R_ERROR_IO (R_ERROR_BASE+2)
/**
* Indicates that the requested operation detected a protocol error.
*/
#define R_ERROR_PROTOCOL (R_ERROR_BASE+3)
/**
* Indicates that the requested operation detected an End-of-File (EOF) error.
*/
#define R_ERROR_EOF (R_ERROR_BASE+4)
/**
* Indicates that the requested operation failed in a memory allocation
* operation.
*/
#define R_ERROR_ALLOC_FAILURE (R_ERROR_BASE+5)
/**
* Indicates that the requested operation is restricted in an evaluation
* version of the library.
*/
#define R_ERROR_EVAL_RESTRICTION (R_ERROR_BASE+6)
/**
* Indicates that the evaluation period of the library has expired.
*/
#define R_ERROR_EVAL_EXPIRED (R_ERROR_BASE+7)
/**
* Indicates that the requested operation detected that a pre-requirement was
* not found.
*/
#define R_ERROR_NOT_FOUND (R_ERROR_BASE+8)
/**
* Indicates that the requested operation detected that a pre-requirement was
* unavailable.
*/
#define R_ERROR_NOT_AVAILABLE (R_ERROR_BASE+9)
/**
* Indicates that the requested operation is not implemented in the current
* instantiation of the library.
*/
#define R_ERROR_NOT_IMPLEMENTED (R_ERROR_BASE+10)
/**
* Indicates that the requested operation is not supported in the current
* instantiation of the library.
*/
#define R_ERROR_NOT_SUPPORTED (R_ERROR_BASE+11)
/**
* Indicates that the requested operation entered an invalid state.
*/
#define R_ERROR_INVALID_STATE \
((R_ERROR_BASE+12) | R_ERROR_FATAL_INTERNAL_ERROR)
/**
* Indicates that the requested operation detected that an initialization
* operation has not been performed.
*/
#define R_ERROR_INIT_NOT_CALLED \
((R_ERROR_BASE+13) | R_ERROR_FATAL_INTERNAL_ERROR)
/**
* Indicates that the requested operation should not have been called.
*/
#define R_ERROR_SHOULD_NOT_HAVE_BEEN_CALLED \
((R_ERROR_BASE+14) | R_ERROR_FATAL_INTERNAL_ERROR)
/**
* Indicates that the requested method is not defined.
*/
#define R_ERROR_METHOD_UNDEFINED \
((R_ERROR_BASE+15) | R_ERROR_FATAL_INTERNAL_ERROR)
/**
* Indicates that the requested operation detected an inadequately sized
* buffer.
*/
#define R_ERROR_BUFFER_TOO_SMALL \
((R_ERROR_BASE+16) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* was passed as <tt>NULL</tt>.
*/
#define R_ERROR_NULL_ARG ((R_ERROR_BASE+17) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed contained a bad or incorrect value.
*/
#define R_ERROR_BAD_VALUE ((R_ERROR_BASE+18) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed was out of the allowed range.
*/
#define R_ERROR_BAD_RANGE ((R_ERROR_BASE+19) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed used a format that is not supported or incorrect.
*/
#define R_ERROR_BAD_FORMAT ((R_ERROR_BASE+20) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed used a type that is not supported or incorrect.
*/
#define R_ERROR_BAD_TYPE ((R_ERROR_BASE+21) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed contained incorrect or invalid data.
*/
#define R_ERROR_BAD_DATA ((R_ERROR_BASE+22) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the requested operation detected that a required argument
* passed contained an incorrect length value.
*/
#define R_ERROR_BAD_LENGTH ((R_ERROR_BASE+23) | R_ERROR_BAD_PARAMETER)
/**
* Indicates that the library instantiation requested is not supported.
*/
#define R_ERROR_RCOM_LIBRARY_NOT_SUPPORTED (R_ERROR_BASE+24)
/**
* Indicates that the request operation was denied.
*/
#define R_ERROR_DENIED (R_ERROR_BASE+25)
/**
* Indicates that authentication is required before the operation
* can succeed.
*/
#define R_ERROR_AUTHENTICATION_REQUIRED (R_ERROR_BASE+26)
/**
* Indicates that a required module was unable to be loaded.
*/
#define R_ERROR_MODULE_LOAD_FAILED \
((R_ERROR_BASE+27)|R_ERROR_FATAL_INTERNAL_ERROR)
/* Resource Manager base for errors */
#define R_COM_ERR_LIB_CTX_BASE 10100
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_R_ERROR_H */

View File

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/*
* ***************************************************************************
*
* Purpose:
*
* This file defines an API for performing stack diagnostics.
*
* It provides:
* Peek Stack Usage statistics
* To use it:
* 1. Build the library without "NO_R_DIAG" defined
* 2. Make a call to R_DIAG_set_stack_datum() prior to
* calling the first library function.
* 3. Add calls to the macro R_DIAG_CHECK_STACK where potential
* high stack usage points are.
* 4. Call R_DIAG_get_stack_low_water_mark() at then end of the
* library calls to return the maximum stack usage OR
* 5. Call R_DIAG_print_stack_depth() to display the peek stack
* usage
*
*
*
* History:
* 3-Aug-00 mjs development
*
* **************************************************************************
*/
#ifndef HEADER_COMMON_R_STDIAG_H
#define HEADER_COMMON_R_STDIAG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NO_R_DIAG
#ifdef NOPROTO
int R_DIAG_set_stack_datum(char *ptr);
int R_DIAG_check_stack(char *ptr, char *file, int line, int hit);
int R_DIAG_get_stack_low_water_mark(int *depth, char **file, int *line,
int *hit);
int R_DIAG_print_stack_depth(BIO *bio);
#else
int R_DIAG_set_stack_datum();
int R_DIAG_check_stack();
int R_DIAG_get_stack_low_water_mark();
int R_DIAG_print_stack_depth();
#endif
#define R_DIAG_CHECK_STACK {\
char r_diag_stack_check_var = 0;\
static int r_diag_stack_check_cnt = 0;\
\
R_DIAG_check_stack(&r_diag_stack_check_var, __FILE__,\
__LINE__,++r_diag_stack_check_cnt);\
}
#else
#define R_DIAG_CHECK_STACK
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_R_STDIAG_H */

View File

@ -0,0 +1,257 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file r_types.h
* This file contains the library structure and type definitions.
*/
#ifndef HEADER_COMMON_R_TYPES_H
#define HEADER_COMMON_R_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup DATA_MNG_FLAGS Data Management Flags
* This section lists the data management flags.
* @{
*/
/**
* @}
*/
/* This gets set if the flags field if the we need to 'free' the
* R_RANDOM when we call R_rand_free(). If it is not set, the
* rand_ctrl will only be called to clean things up.
*/
#define R_RANDOM_FLG_MALLOCED 0x01
/* portable form of a random callback function */
/**
* @typedef R_RANDOM
* The random object type.
*/
typedef struct r_random_st R_RANDOM;
/**
* This structure is used by the random object type.
*/
struct r_random_st
{
/**
* A method function for generation of random data.
*
* @see R_rand_bytes().
*/
int (*rand_bytes)(R_RANDOM *ctx,unsigned char *bytes,int len);
/**
* A method function for seeding of the random generator.
* @see R_rand_seed().
*/
int (*rand_seed)(R_RANDOM *ctx,unsigned char *bytes,int len);
/**
* A method function for control of the random generator used by
* other functions as a single interface.
*
* @see R_rand_entropy_count(), R_rand_set_entropy_func(),
* R_rand_get_entropy_func(), R_rand_load_file(), R_rand_write_file()
* and R_rand_file_name().
*/
int (*rand_ctrl)(R_RANDOM *ctx,int op,char *arg);
/**
* The data used by the random implementation.
*/
char *arg;
/**
* A method flag for used for keeping the state of the #R_RANDOM.
*/
int flags; /* normally set to zero */
};
/**
* @typedef R_SURRENDER
* The surrender function and argument.
*/
typedef struct r_surrender_st R_SURRENDER;
/**
* This structure provides a status update of a time intensive operation. It
* also allows you to abort the operation if required.
*/
struct r_surrender_st
{
/* Return 0 to continue, non-zero to 'cancel' function */
/**
* The surrender function pointer used as a generic method of
* passing user-defined callback or information collection functions.
*/
int (*callback)(R_SURRENDER *ctx,int function,int num);
/**
* The argument data used by the callback operation.
*/
char *arg;
};
typedef struct r_fixed_point_number_st R_FIXED_POINT_NUMBER;
struct r_fixed_point_number_st
{
unsigned long hi;
unsigned long lo;
};
/**
* @typedef R_INDEXED_INFO
* This structure details the index containing information for get and set
* functions.
*/
typedef struct r_indexed_info_st R_INDEXED_INFO;
/** This structure details the index containing information for get and set
* functions.
*/
struct r_indexed_info_st
{
/** The index into the list of the item to work with. */
int index;
/** The data of the item in the list. */
void *data;
/** The length of the data. */
unsigned int len;
/** The data value as an integer. */
int value;
};
/**
* @typedef R_ID_INFO
* The information to work with requires a second identity value to find it.
*/
typedef struct r_id_info_st R_ID_INFO;
/** The information to get or set requires a second information identifier.
* This type is used when calling set_info and get_info to get a number of
* information items in one call.
*/
struct r_id_info_st
{
/** The information identifier. */
int info_id;
/** The information data associated with the identifier. */
void *value;
};
/** @defgroup R_FLAG_COPY_IDS Copy Flag Identifiers
*
* This section provides information on the copy mode. When data is passed
* to/from the library you can specify whether or not the copy should be done
* by value, by reference or by direct assignment.
* @ingroup DATA_MNG_FLAGS
* @{
*/
/**
* The copy flag. When data is passed to/from the library you can specify
* whether or not the copy should be done by value, by reference or
* by direct assignment.
*/
typedef int R_FLAG_COPY;
/*
* action flag app lib
* obj_get BY_VAL F X
* BY_REF X F [app will not free "obj" until it is
* BY_ASSIGN F X finished with the returned reference]
* obj_set BY_VAL F X
* BY_REF F X [app will not free passed reference
* BY_ASSIGN X F until after it has freed "obj"]
*
* BY_REF makes the lifetime of the two objects linked and it is up to
* the application to manage the objects in a manner that preserves this
* relationship.
*/
/**
* Indicates to copy by value. A complete clone of the object is made.
* The lifecycles of the two objects are independent.
*/
#define R_FLAG_COPY_BY_VALUE 0x0000
/**
* Indicates to copy by reference. A reference to the object is made.
* The lifecycles of objects sharing references are linked.
*/
#define R_FLAG_COPY_BY_REFERENCE 0x0001
/**
* Indicates to copy by assignment. The object is assigned to the required
* party. The caller does not keep a reference to the passed object.
*/
#define R_FLAG_COPY_BY_ASSIGN 0x0002
/**
* Indicates to copy using the default flag settings.
*/
#define R_FLAG_COPY_DEFAULT R_FLAG_COPY_BY_VALUE
/**
* @}
*/
/** @defgroup R_FLAG_SHARE_IDS Shared Flag Identifiers
*
* This section provides information on the shared flags available.
* @ingroup DATA_MNG_FLAGS
* @{
*/
/**
* The constructor flag. Indicates whether or not it is permissible to share
* the internal state between objects.
*/
typedef int R_FLAG_SHARE;
/**
* Indicates to share nothing. The states of the two objects are completely
* separate.
*/
#define R_FLAG_SHARE_NONE 0x0000
/**
* Indicates to share data. Constructed objects may reference the state of
* the object from which it was constructed. The lifecycles of the two objects
* are linked.
*/
#define R_FLAG_SHARE_DATA 0x0001
/** Indicates the share default in which nothing is shared. */
#define R_FLAG_SHARE_DEFAULT R_FLAG_SHARE_NONE
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_SHA_H
#define HEADER_COMMON_SHA_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(CCONV)
#define CCONV
#endif
#ifndef PRE_CCONV
#define PRE_CCONV
#endif
#define SHA_CBLOCK 64
#define SHA_LBLOCK 16
#define SHA_BLOCK 16
#define SHA_LAST_BLOCK 56
#define SHA_LENGTH_BLOCK 8
#define SHA_DIGEST_LENGTH 20
/* the default is to use unsigned long */
#if !defined(OPT_SHA_INT) && !defined(OPT_SHA_LONG)
#define OPT_SHA_LONG
#endif
#ifdef OPT_SHA_LONG
#define SHA_LONG unsigned long
#endif
#ifdef OPT_SHA_INT
#define SHA_LONG unsigned int
#endif
typedef struct sha_ctx_st SHA_CTX;
struct sha_ctx_st
{
SHA_LONG h0,h1,h2,h3,h4;
SHA_LONG Nl,Nh;
SHA_LONG data[SHA_LBLOCK];
int num;
void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c, const unsigned char *W,
int num);
};
#ifndef NOPROTO
int SHA1_Setup(SHA_CTX *c, void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c,
const unsigned char *W, int num));
void SHA_Init(SHA_CTX *c);
void SHA_Update(SHA_CTX *c, const unsigned char *data, unsigned long len);
void SHA_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
void SHA_Transform(SHA_CTX *c, const unsigned char *data);
void SHA1_Init(SHA_CTX *c);
void SHA1_Update(SHA_CTX *c, const unsigned char *data, unsigned long len);
void SHA1_Final(unsigned char *md, SHA_CTX *c);
unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
#else
void SHA_Init();
void SHA_Update();
void SHA_Final();
unsigned char *SHA();
void SHA_Transform();
void SHA1_Init();
void SHA1_Update();
void SHA1_Final();
unsigned char *SHA1();
void SHA1_Transform();
#endif
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_SHA_H */

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* sha1.h
*
* Description:
* This is the header file for code which implements the Secure
* Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
* April 17, 1995.
*
* Many of the variable names in this code, especially the
* single character names, were used because those were the names
* used in the publication.
*
* Please read the file sha1.c for more information.
*
*/
#ifndef _SHA1_H_
#define _SHA1_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _SHA_enum_
#define _SHA_enum_
enum
{
shaSuccess = 0,
shaNull, /* Null pointer parameter */
shaInputTooLong, /* input data too long */
shaStateError /* called Input after Result */
};
#endif
/*
* This structure will hold context information for the SHA-1
* hashing operation
*/
typedef struct SHA1Context
{
unsigned long Intermediate_Hash[20/4]; /* Message Digest */
unsigned long Length_Low; /* Message length in bits */
unsigned long Length_High; /* Message length in bits */
int Message_Block_Index; /* Index into message block array */
unsigned char Message_Block[64]; /* 512-bit message blocks */
int Computed; /* Is the digest computed? */
int Corrupted; /* Is the message digest corrupted? */
} SHA1Context;
/*
* Function Prototypes
*/
int SHA1Reset( SHA1Context *);
int SHA1Input( SHA1Context *,
const unsigned char *,
unsigned int);
int SHA1Result( SHA1Context *,
unsigned char Message_Digest[20]);
#if defined( SHA1_TEST )
int SHA1Test( );
#endif // SHA1_TEST
#ifdef __cplusplus
}
#endif
#endif // _SHA1_H_

View File

@ -0,0 +1,290 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef HEADER_COMMON_SHA_LOCL_H
#define HEADER_COMMON_SHA_LOCL_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef STANDALONE
#include "r_com.h"
#else
#if 0 //RSA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Memcpy memcpy
#define Memset memset
#define Strcpy strcpy
#else //NITRO
#include "acmemory.h"
#define Malloc(a) ACMemory_Alloc(a)
#define Free(a) ACMemory_Free(a)
#define Memset(a,b,c) ACMemory_Memset(a,b,c)
#define Memcpy(a,b,c) ACMemory_Memcpy(a,b,c)
#endif
#endif
#ifdef undef
/* one or the other must be defined */
#ifndef SHA_1 /* FIPE 180-1 */
#define SHA_0 /* FIPS 180 */
#endif
#endif
#define ULONG unsigned long
#define UCHAR unsigned char
#define UINT unsigned int
#ifdef NOCONST
#define const
#endif
#undef c2nl
#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++))) ))
#undef p_c2nl
#define p_c2nl(c,l,n) { \
switch (n) { \
case 0: l =((unsigned long)(*((c)++)))<<24; \
case 1: l|=((unsigned long)(*((c)++)))<<16; \
case 2: l|=((unsigned long)(*((c)++)))<< 8; \
case 3: l|=((unsigned long)(*((c)++))); \
} \
}
#undef c2nl_p
/* NOTE the pointer is not incremented at the end of this */
#define c2nl_p(c,l,n) { \
l=0; \
(c)+=n; \
switch (n) { \
case 3: l =((unsigned long)(*(--(c))))<< 8; \
case 2: l|=((unsigned long)(*(--(c))))<<16; \
case 1: l|=((unsigned long)(*(--(c))))<<24; \
} \
}
#undef p_c2nl_p
#define p_c2nl_p(c,l,sc,len) { \
switch (sc) \
{ \
case 0: l =((unsigned long)(*((c)++)))<<24; \
if (--len == 0) break; \
case 1: l|=((unsigned long)(*((c)++)))<<16; \
if (--len == 0) break; \
case 2: l|=((unsigned long)(*((c)++)))<< 8; \
} \
}
#undef nl2c
#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
#undef c2l
#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
l|=(((unsigned long)(*((c)++)))<< 8), \
l|=(((unsigned long)(*((c)++)))<<16), \
l|=(((unsigned long)(*((c)++)))<<24))
#undef p_c2l
#define p_c2l(c,l,n) { \
switch (n) { \
case 0: l =((unsigned long)(*((c)++))); \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
case 3: l|=((unsigned long)(*((c)++)))<<24; \
} \
}
#undef c2l_p
/* NOTE the pointer is not incremented at the end of this */
#define c2l_p(c,l,n) { \
l=0; \
(c)+=n; \
switch (n) { \
case 3: l =((unsigned long)(*(--(c))))<<16; \
case 2: l|=((unsigned long)(*(--(c))))<< 8; \
case 1: l|=((unsigned long)(*(--(c)))); \
} \
}
#undef p_c2l_p
#define p_c2l_p(c,l,sc,len) { \
switch (sc) \
{ \
case 0: l =((unsigned long)(*((c)++))); \
if (--len == 0) break; \
case 1: l|=((unsigned long)(*((c)++)))<< 8; \
if (--len == 0) break; \
case 2: l|=((unsigned long)(*((c)++)))<<16; \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff))
#ifdef OPT_SHA_B_ENDIAN
#define B_ENDIAN
#endif
#ifdef OPT_SHA_L_ENDIAN
#define L_ENDIAN
#endif
#undef ROTATE
#if defined(WIN32)
#define ROTATE(a,n) _lrotl(a,n)
#else
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
#endif
/* byte order reversal */
#if defined(WIN32)
/* 5 instructions with rotate instruction, else 9 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
(a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
}
#else
/* 6 instructions with rotate instruction, else 8 */
#define Endian_Reverse32(a) \
{ \
unsigned long l=(a); \
l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
(a)=ROTATE(l,16L); \
}
#endif
/* F() below can be
* simplified to the code in F_00_19.
* #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
* another tweak to be made
* in F_40_59, (x&a)|(y&a) -> (x|y)&a
*/
#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
#define F_60_79(b,c,d) F_20_39(b,c,d)
#ifdef SHA_0
#undef Xupdate
#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\
(ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);
#endif
#ifdef SHA_1
#undef Xupdate
#define Xupdate(a,i,ia,ib,ic,id) (a)=\
(ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\
X[(i)&0x0f]=(a)=ROTATE((a),1);
#endif
#define BODY_00_15(i,a,b,c,d,e,f,xa) \
(f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_60_79(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
(b)=ROTATE((b),30);
/*
* The CodeWarrior compiler has a problem correctly expanding things like
*
* (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d));
*
* so we separate this to 3 explicit adds, just for PalmOS.
*/
#ifndef UNDER_PALMOS
#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_32_39(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_40_59(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
(b)=ROTATE((b),30);
#else /* UNDER_PALMOS */
#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e); \
(f)+=K_00_19; \
(f)+=ROTATE((a),5)+F_00_19((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \
Xupdate(f,i,xa,xb,xc,xd); \
(f)+=(e); \
(f)+=K_20_39; \
(f)+=ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_32_39(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e); \
(f)+=K_20_39; \
(f)+=ROTATE((a),5)+F_20_39((b),(c),(d)); \
(b)=ROTATE((b),30);
#define BODY_40_59(i,a,b,c,d,e,f,xa) \
Xupdate(f,i,xa,xa,xa,xa); \
(f)+=(e); \
(f)+=K_40_59; \
(f)+=ROTATE((a),5)+F_40_59((b),(c),(d)); \
(b)=ROTATE((b),30);
#endif /* UNDER_PALMOS */
#ifdef __cplusplus
}
#endif
#endif /* HEADER_COMMON_SHA_LOCL_H */

View File

@ -0,0 +1,306 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
//
// BN系関数用のメモリ関連処理を置き換え
//
#include <nitro.h>
#include "acmemory.h"
/*
head tail
| | | |
+--------+---------+----....----+---------+--------+
|block |check |buffer |check |block |
+--------+---------+----....----+---------+--------+
|4byte |4byte |Upper4(size)|4byte |4byte |
<------------------ 4 * n ------------------->
block = n = (4 * 4 + Upper4(size)) / 4
check = 0x0F5555F0使0x0FAAAAF0使
*/
unsigned long aACMemoryPoolA[ 16 ];
unsigned long aACMemoryPool[ 1024 * 32 / sizeof (unsigned long) ]; // 32K
unsigned long aACMemoryPoolB[ 16 ];
#define ACMEMORYPOOL_HEAD (aACMemoryPool)
#define ACMEMORYPOOL_TAIL (aACMemoryPool + sizeof aACMemoryPool / sizeof (unsigned long))
#define ACMEMORYPOOL_SIZE ((unsigned long)ACMEMORYPOOL_TAIL - (unsigned long)ACMEMORYPOOL_HEAD)
#define ACMEMORY_CHECK_BASE 0xF000000F
#define ACMEMORY_CHECK_FREE (0x00555500 | ACMEMORY_CHECK_BASE)
#define ACMEMORY_CHECK_USED (0x00AAAA00 | ACMEMORY_CHECK_BASE)
#define ACMemory_Lower4( _size ) (((_size) ) & 0xFFFFFFFC)
#define ACMemory_Upper4( _size ) (((_size) + 3) & 0xFFFFFFFC)
#define pACMemory_FromHeadToBody( _head ) ((unsigned long*)(((volatile unsigned long*)(_head)) + 2))
#define pACMemory_FromBodyToHead( _body ) ((unsigned long*)(((volatile unsigned long*)(_body)) - 2))
#define pACMemory_FromHeadToTail( _head ) ((unsigned long*)(((volatile unsigned long*)(_head)) + nACMemory_HeadBlock( _head )))
#define pACMemory_FromTailToHead( _tail ) ((unsigned long*)(((volatile unsigned long*)(_tail)) - nACMemory_TailBlock( _tail )))
#define nACMemory_HeadBlock( _head ) (((volatile unsigned long*)(_head))[+0])
#define nACMemory_HeadCheck( _head ) (((volatile unsigned long*)(_head))[+1])
#define nACMemory_TailBlock( _tail ) (((volatile unsigned long*)(_tail))[-1])
#define nACMemory_TailCheck( _tail ) (((volatile unsigned long*)(_tail))[-2])
//#define USE_OSALLOC
//#define USE_ACMEMORY_DEBUGDUMP
//#define USE_ACMEMORY_DEBUGFILL
//
#if defined( USE_ACMEMORY_DEBUGDUMP )
static
void acMemory_DebugDump( )
{
unsigned long* ptr = ACMEMORYPOOL_HEAD;
//
OS_Printf( "----ACMemory_Dump [0x%.8x - 0x%.8x : 0x%.8x ]----\n", ACMEMORYPOOL_HEAD, ACMEMORYPOOL_TAIL, ACMEMORYPOOL_SIZE );
for ( ; (unsigned long)ptr < (unsigned long)ACMEMORYPOOL_TAIL; )
{
OS_Printf( " [0x%.8x - 0x%.8x] (0x%.8x) <%c> ",
ptr,
pACMemory_FromHeadToTail( ptr ),
nACMemory_HeadBlock( ptr ),
nACMemory_HeadCheck( ptr ) == ACMEMORY_CHECK_USED ? '*' : '-' );
//OS_Printf( "0x%.8x 0x%.8x", nACMemory_HeadBlock( ptr ), nACMemory_HeadCheck( ptr ) );
//OS_Printf( " .... " );
ptr += nACMemory_HeadBlock( ptr );
//OS_Printf( "0x%.8x 0x%.8x", nACMemory_TailCheck( ptr ), nACMemory_TailBlock( ptr ) );
OS_Printf( "\n" );
OS_PrintServer();
}
ptr = 0;
}
#define ACMemory_DebugDump( ) acMemory_DebugDump( )
#else
#define ACMemory_DebugDump( )
#endif //USE_ACMEMORY_DEBUGDUMP
//
#if defined( USE_ACMEMORY_DEBUGFILL )
static
void acMemory_DebugFill( void* ptr, int cnt, int val )
{
(void)ACMemory_Memset( ptr, val, cnt );
}
#define ACMemory_DebugFill( _ptr, _cnt, _val ) acMemory_DebugFill( _ptr, _cnt, _val )
#else
#define ACMemory_DebugFill( _ptr, _cnt, _val )
#endif //USE_ACMEMORY_DEBUGFILL
//
void ACMemory_Clear( )
{
unsigned long* head = ACMEMORYPOOL_HEAD;
unsigned long* tail = ACMEMORYPOOL_TAIL;
unsigned long block;
unsigned long check;
block = ACMEMORYPOOL_SIZE / 4;
check = ACMEMORY_CHECK_FREE;
nACMemory_HeadBlock( head ) = block;
nACMemory_HeadCheck( head ) = check;
nACMemory_TailBlock( tail ) = block;
nACMemory_TailCheck( tail ) = check;
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0xFF );
ACMemory_DebugDump( );
}
//
void* ACMemory_Alloc( u32 size )
{
#if defined( USE_OSALLOC )
OSIntrMode nOSIntrMode;
void* alloc = NULL;
nOSIntrMode = OS_DisableInterrupts( );
alloc = OS_Alloc( size );
(void)OS_RestoreInterrupts( nOSIntrMode );
return alloc;
#else
unsigned long* head = ACMEMORYPOOL_HEAD;
unsigned long* tail = ACMEMORYPOOL_TAIL;
unsigned long block, oldblock, newblock;
unsigned long check, oldcheck, newcheck;
if ( !size ) return 0;
//
if ( size < 16 ) size = 16;
block = 4 + ACMemory_Upper4( size ) / 4;
check = ACMEMORY_CHECK_USED;
//
for ( ; ; )
{
if ( (unsigned long)head >= (unsigned long)tail )
{
head = 0;
break;
}
newblock = nACMemory_HeadBlock( head );
newcheck = nACMemory_HeadCheck( head );
if ( newcheck == check )
{
head += newblock;
continue ;
}
if ( newblock < block + 4 + 4 )
{
head += newblock;
continue ;
}
break;
}
if ( !head ) return 0;
//
oldblock = nACMemory_HeadBlock( head );
oldcheck = nACMemory_HeadCheck( head );
nACMemory_HeadBlock( head ) = block;
nACMemory_HeadCheck( head ) = check;
tail = pACMemory_FromHeadToTail( head );
nACMemory_TailBlock( tail ) = block;
nACMemory_TailCheck( tail ) = check;
if ( (unsigned long)tail < (unsigned long)ACMEMORYPOOL_TAIL )
{
nACMemory_HeadBlock( tail ) = oldblock - block;
nACMemory_HeadCheck( tail ) = oldcheck;
tail = pACMemory_FromHeadToTail( tail );
nACMemory_TailBlock( tail ) = oldblock - block;
nACMemory_TailCheck( tail ) = oldcheck;
}
//
(void)ACMemory_Memset( pACMemory_FromHeadToBody( head ), 0x00, (block - 4) * 4 );
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0x00 );
ACMemory_DebugDump( );
return (void*)pACMemory_FromHeadToBody( head );
#endif
}
//
void ACMemory_Free( void* adrs )
{
#if defined( USE_OSALLOC )
OSIntrMode nOSIntrMode;
nOSIntrMode = OS_DisableInterrupts( );
OS_Free( adrs );
(void)OS_RestoreInterrupts( nOSIntrMode );
#else
unsigned long* work;
unsigned long* head;
unsigned long* tail;
unsigned long block;
unsigned long check;
if ( !adrs ) return ;
//
head = pACMemory_FromBodyToHead( adrs );
tail = pACMemory_FromHeadToTail( head );
block = nACMemory_HeadBlock( head );
check = ACMEMORY_CHECK_FREE;
//
if ( nACMemory_HeadBlock( head ) != nACMemory_TailBlock( tail ) )
return ;
if ( nACMemory_HeadCheck( head ) != nACMemory_TailCheck( tail ) )
return ;
//
if ( (unsigned long)head != (unsigned long)ACMEMORYPOOL_HEAD )
{
work = pACMemory_FromTailToHead( head );
if ( nACMemory_HeadCheck( work ) == check )
{
block += nACMemory_HeadBlock( work );
head = work;
}
}
//
if ( (unsigned long)tail != (unsigned long)ACMEMORYPOOL_TAIL )
{
work = pACMemory_FromHeadToTail( tail );
if ( nACMemory_TailCheck( work ) == check )
{
block += nACMemory_TailBlock( work );
tail = work;
}
}
//
nACMemory_HeadBlock( head ) = nACMemory_TailBlock( tail ) = block;
nACMemory_HeadCheck( head ) = nACMemory_TailCheck( tail ) = check;
ACMemory_DebugFill( pACMemory_FromHeadToBody( head ), (block - 4) * 4, 0xFF );
ACMemory_DebugDump( );
#endif
}
//
void* ACMemory_Memset( void* adrs, u32 val, u32 cnt )
{
if ( !adrs ) return 0;
MI_CpuFill8( (void*)adrs, (u8)val, (u32)cnt );
return adrs;
}
//
void* ACMemory_Memcpy( void* dst, void* src, u32 cnt )
{
if ( !dst || !src ) return 0;
MI_CpuCopy8( (const void*)src, (void*)dst, (u32)cnt );
return dst;
}

View File

@ -0,0 +1,453 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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 <sysmenu/acsign.h>
#include "acmemory.h"
// SHA1
#include "sha.h"
#include "sha1dgst.c"
#define _DLENGTH_ (160/8)
#define _BLENGTH_ (512/8)
#define HASHContext SHA_CTX
#define HASHReset( _context ) (void)SHA1_Init( _context )
#define HASHSetSource( _context, _ptr, _len ) (void)SHA1_Update( _context, _ptr, _len )
#define HASHGetDigest( _context, _ptr ) (void)SHA1_Final( _ptr, _context )
// BN
#include "bn.h"
#include "bn_lib.c"
#include "bn_asm.c"
#include "bn_comba.c"
#include "bn_lsh.c"
#include "bn_rsh.c"
#include "bn_word.c"
#include "bn_add.c"
#include "bn_mul.c"
#include "bn_div.c"
#include "bn_exp.c"
#include "bn_sqr.c"
#include "bn_fm_w.c"
#include "bn_gcd.c"
#include "bn_ex_str.c"
#include "bn_ms_w.c"
//#include "bn_me.c"
#include "bn_rec.c"
#include "bn_mont.c"
#include "bn_recp.c"
#include "bn_wdiv.c"
#include "bn_r_exp.c"
#include "bn_m_exp.c"
#if !defined( RSA_ENC_DEC )
#define BER_NULL 5
#define BER_OBJECT 6
#define BER_SEQUENCE 16
#define BER_OCTET_STRING 4
#define BER_CONSTRUCTED 0x20
//
// rsa_padding_check_pkcs1_type_1関数相当
//
static
int decode_padding( unsigned char* pdst_adrs, unsigned int* pdst_size,
unsigned char* psrc_adrs, unsigned int nsrc_size,
int length )
{
unsigned char* p;
unsigned char* q;
unsigned char* pe;
int i;
if (nsrc_size >= length )
return 0;
/* The leading 0 was removed by the bignum->bin conversion */
if (nsrc_size < 10)
return 0;
p = psrc_adrs;
pe = &(psrc_adrs[nsrc_size]);
/* if (p[0] != 0) goto err; */
if ( p[0] != 1 )
return 0;
p++;
for ( i = 0; i < 8; i++ )
{
if ( *(p++) != 0xFF )
return 0;
}
for ( ; p != pe; p++ )
{
if ( *p != 0xFF )
break;
}
if ( p == pe )
return 0;
if ( *(p++) != 0 )
return 0;
*pdst_size = (unsigned int)((int)pe - (int)p);
q = pdst_adrs;
while ( p != pe )
*(q++)= *(p++);
return 1;
}
//
//
//
static
int pk_skip( unsigned char **datap, unsigned int *dlenp,
unsigned char type, unsigned int *lenp)
{
unsigned char *data = *datap;
unsigned int dlen = *dlenp;
unsigned int len = 0;
unsigned char l;
if (*(data++) != type)
return 0;
if (dlen < 1)
return 0;
dlen--;
if ( (*data & 0x80) != 0 )
{
l = (unsigned char)( *data & 0x7F );
if (dlen < (unsigned int)l + 1)
return 0;
dlen -= l;
if (lenp != NULL)
{
data++;
do
{
len <<= 7;
len += (*data & 0x7f);
l--;
}
while (l > 0);
}
else
{
data += l;
}
}
else
{
len = *data;
data++;
if (dlen < 1)
return 0;
dlen--;
}
*datap = data;
*dlenp = dlen;
if (lenp != NULL)
{
*lenp = len;
}
return 1;
}
//
// PK_decode_sighash関数相当
//
static
int decode_sighash( unsigned char* data, unsigned int dlen,
unsigned char** ppdgst_adrs, unsigned int* pdgst_size,
unsigned char** pphash_adrs, unsigned int* phash_size )
{
#if 0
/* 01 */ OB_cmpu(BER_SEQUENCE, 0, 0),
/* 02 */ OB_down(0, 1),
/* 03 */ OB_cmpu(BER_SEQUENCE, 0, 0),
/* 04 */ OB_down(0, 1),
/* 05 */ OB_cmpu(BER_OBJECT, 0, 0),
/* 06 */ OB_call(OB_F_SET, PK_TYPE_SIG, PK_SIG_DIGEST_OID),
/* go up a level - we got all we need out of the
* sequence that contains the parameters
* - we could OB_next(0,1) and check that we have BER_NULL
* as then next item but there is no real need to do that
*/
/* 07 */ OB_up(0, 1),
/* 08 */ OB_next(0, 1),
/* 09 */ OB_cmpu(BER_OCTET_STRING, 0, 0),
/* 10 */ OB_call(OB_F_SET, PK_TYPE_SIG, PK_SIG_HASH),
/* 11 */ OB_exit(0),
/* 12 */ OB_FINISH,
#endif
unsigned int len;
if ( !pk_skip(&data, &dlen, (BER_SEQUENCE|BER_CONSTRUCTED), NULL) )
return 0;
if ( !pk_skip(&data, &dlen, (BER_SEQUENCE|BER_CONSTRUCTED), NULL) )
return 0;
if ( !pk_skip(&data, &dlen, (BER_OBJECT), &len) )
return 0;
/*
if (digest != NULL)
{
digest->adrs = data;
digest->size = len;
}
*/
if ( ppdgst_adrs ) *ppdgst_adrs = data;
if ( pdgst_size ) *pdgst_size = len;
data += len;
if (dlen < len)
return 0;
dlen -= len;
if ( !pk_skip(&data, &dlen, BER_NULL, &len) )
return 0;
data += len;
if (dlen < len)
return 0;
dlen -= len;
if ( !pk_skip(&data, &dlen, (BER_OCTET_STRING), &len) )
return 0;
/*
if (hash != NULL)
{
hash->adrs = data;
hash->size = len;
}
*/
if ( pphash_adrs ) *pphash_adrs = data;
if ( phash_size ) *phash_size = len;
return 1;
}
#endif
//
#define SGN_LEN 128
#define MOD_LEN 128
#define EXP_LEN 3
int ACSign_Decrypto(
void* buffer, // 出力領域
void* sgn_ptr, // データへのポインタ
void* key_ptr // キーへのポインタ
)
{
BN_CTX* ctx;
BIGNUM src, dst, exp, mod;
void* exp_ptr;
void* mod_ptr;
int nTmp, nWrk;
unsigned char* pAdrs = 0;
unsigned int nSize = 0;
unsigned long nDummyExp = 0x00010001; // 65537固定
unsigned long aBufferA[ 256 / sizeof (unsigned long) ];
unsigned long aBufferB[ 256 / sizeof (unsigned long) ];
if ( !buffer ) return 0;
if ( !sgn_ptr ) return 0;
if ( !key_ptr ) return 0;
//
ACMemory_Clear( );
//
exp_ptr = &nDummyExp;
mod_ptr = key_ptr;
(void)ACMemory_Memset( aBufferA, 0, sizeof aBufferA );
(void)ACMemory_Memset( aBufferB, 0, sizeof aBufferB );
ctx=BN_CTX_new();
BN_init( &src );
BN_init( &dst );
BN_init( &exp );
BN_init( &mod );
(void)BN_bin2bn( sgn_ptr, SGN_LEN, &src );
(void)BN_bin2bn( exp_ptr, EXP_LEN, &exp );
(void)BN_bin2bn( mod_ptr, MOD_LEN, &mod );
nTmp = BN_mod_exp( &dst, &src, &exp, &mod, ctx );
nTmp = BN_bn2bin( &dst, (unsigned char*)aBufferA );
BN_free( &src );
BN_free( &dst );
BN_free( &exp );
BN_free( &mod );
if (ctx != NULL)
BN_CTX_free(ctx);
#if defined( RSA_ENC_DEC )
pAdrs = (unsigned char*)aBufferA + 4; //ダミー部4バイトは読み飛ばし
nSize = nTmp;
(void)ACMemory_Memcpy( buffer, pAdrs, _DLENGTH_ * 4 );
#else
if ( !decode_padding( (unsigned char*)aBufferB, (unsigned int*)&nWrk, (unsigned char*)aBufferA, (unsigned int )nTmp, SGN_LEN ) )
return 0;
if ( !decode_sighash( (unsigned char*)aBufferB, (unsigned int)nWrk, NULL, NULL, (unsigned char**)&pAdrs, (unsigned int*)&nSize ) )
return 0;
if ( nSize != _DLENGTH_ )
return 0;
(void)ACMemory_Memcpy( buffer, pAdrs, _DLENGTH_ * 1 );
#endif
return 1;
}
//
#define ROMH_SIZE 0x0160
int ACSign_Digest(
void* buffer, // 出力領域
void* romh_ptr, // データへのポインタ
void* mbin_ptr, // データへのポインタ
int mbin_len, // データの長さ
void* sbin_ptr, // データへのポインタ
int sbin_len, // データの長さ
u32 serial_num // シリアルナンバー
)
{
#if defined( RSA_ENC_DEC )
HASHContext context;
if ( !buffer ) return 0;
if ( !romh_ptr ) return 0;
if ( !mbin_ptr || !mbin_len ) return 0;
if ( !sbin_ptr || !sbin_len ) return 0;
HASHReset( &context );
HASHSetSource( &context, romh_ptr, ROMH_SIZE );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 0 );
HASHReset( &context );
HASHSetSource( &context, mbin_ptr, mbin_len );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 1 );
HASHReset( &context );
HASHSetSource( &context, sbin_ptr, sbin_len );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 2 );
HASHReset( &context );
HASHSetSource( &context, buffer, _DLENGTH_ * 3 );
HASHGetDigest( &context, (unsigned char*)buffer + _DLENGTH_ * 3 );
#else
HASHContext context;
unsigned char aBuffer[ (_DLENGTH_ * 3 + sizeof (unsigned long)) ];
if ( !buffer ) return 0;
if ( !romh_ptr ) return 0;
if ( !mbin_ptr || !mbin_len ) return 0;
if ( !sbin_ptr || !sbin_len ) return 0;
HASHReset( &context );
HASHSetSource( &context, romh_ptr, ROMH_SIZE );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 0 );
HASHReset( &context );
HASHSetSource( &context, mbin_ptr, mbin_len );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 1 );
HASHReset( &context );
HASHSetSource( &context, sbin_ptr, sbin_len );
HASHGetDigest( &context, (unsigned char*)aBuffer + _DLENGTH_ * 2 );
// シリアル番号分 今は0固定
aBuffer[ (_DLENGTH_ * 3) + 0 ] = (unsigned char)((serial_num >> 0) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 1 ] = (unsigned char)((serial_num >> 8) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 2 ] = (unsigned char)((serial_num >> 16) & 0xFF);
aBuffer[ (_DLENGTH_ * 3) + 3 ] = (unsigned char)((serial_num >> 24) & 0xFF);
HASHReset( &context );
HASHSetSource( &context, (unsigned char*)aBuffer, _DLENGTH_ * 3 + sizeof (unsigned long) );
HASHGetDigest( &context, (unsigned char*)buffer );
#endif
return 1;
}
//
int ACSign_Compare(
void* decrypto, // ACSign_Decryptoの出力
void* digest // ACSign_Digestの出力
)
{
unsigned char* ptrA = (unsigned char*)decrypto;
unsigned char* ptrB = (unsigned char*)digest;
int loop;
int test = 1;
if ( !decrypto ) return 0;
if ( !digest ) return 0;
#if defined( RSA_ENC_DEC )
for ( loop = 0; loop < _DLENGTH_ * 4; loop++ )
#else
for ( loop = 0; loop < _DLENGTH_ * 1; loop++ )
#endif
{
if ( *ptrA++ != *ptrB++ )
{
test = 0;
break;
}
}
return test;
}

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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 <nitro.h>
#include <sysmenu/acsign.h>
#include <string.h>
#define AUTH_KEY_BUFFER_LEN 128
#define MB_AUTH_SIGN_SIZE (128) /* digital sign size */
typedef struct MbAuthCode
{
char magic_code[2]; // マジックナンバー
u16 version; // バージョン
u8 sign[MB_AUTH_SIGN_SIZE]; // 署名
u32 serial_number; // シリアル番号
} MbAuthCode; // 16byte
static u8 key_buffer[AUTH_KEY_BUFFER_LEN] = {
0x9E,0xC1,0xCC,0xC0,0x4A,0x6B,0xD0,0xA0,0x6D,0x62,0xED,0x5F,0x15,0x67,0x87,0x12,
0xE6,0xF4,0x77,0x1F,0xD8,0x5C,0x81,0xCE,0x0C,0xD0,0x22,0x31,0xF5,0x89,0x08,0xF5,
0xBE,0x04,0xCB,0xC1,0x4F,0x63,0xD9,0x5A,0x98,0xFF,0xEB,0x36,0x0F,0x9C,0x5D,0xAD,
0x15,0xB9,0x99,0xFB,0xC6,0x86,0x2C,0x0A,0x0C,0xFC,0xE6,0x86,0x03,0x60,0xD4,0x87,
0x28,0xD5,0x66,0x42,0x9C,0xF7,0x04,0x14,0x4E,0x6F,0x73,0x20,0xC3,0x3E,0x3F,0xF5,
0x82,0x2E,0x78,0x18,0xD6,0xCD,0xD5,0xC2,0xDC,0xAA,0x1D,0x34,0x91,0xEC,0x99,0xC9,
0xF7,0xBF,0xBF,0xA0,0x0E,0x1E,0xF0,0x25,0xF8,0x66,0x17,0x54,0x34,0x28,0x2D,0x28,
0xA3,0xAE,0xF0,0xA9,0xFA,0x3A,0x70,0x56,0xD2,0x34,0xA9,0xC5,0x9E,0x5D,0xF5,0xE1
};
int ACSignDecrpto(void *output_buffer, MBDownloadFileInfo *download_file_info_buf)
{
return ACSign_Decrypto(output_buffer,
((MbAuthCode *)(download_file_info_buf->auth_code))->sign,
key_buffer);
}
int ACSignDigest(void *input_buffer, MBDownloadFileInfo *download_file_info_buf)
{
int ret_code;
u8 digest_output_buffer[AUTH_BUFFER_LEN];
ret_code = ACSign_Digest((void *)digest_output_buffer, // 出力領域 20 Bytes
(void *)(download_file_info_buf->seg[0].recv_addr),
(void *)(download_file_info_buf->seg[1].recv_addr),
(int)(download_file_info_buf->seg[1].size),
(void *)(download_file_info_buf->seg[2].recv_addr),
(int)(download_file_info_buf->seg[2].size),
((MbAuthCode *)(download_file_info_buf)->auth_code)->serial_number // serial_number
);
if( ret_code == 0 )
{
return ret_code; // failure
}
return ACSign_Compare(
input_buffer, // ACSign_Decryptoの出力
(void*)digest_output_buffer // ACSign_Digestの出力
);
}
#if 0
void* doAlloc( int size )
{
OSIntrMode nOSIntrMode;
void* alloc = NULL;
nOSIntrMode = OS_DisableInterrupts( );
alloc = OS_Alloc( size );
(void)OS_RestoreInterrupts( nOSIntrMode );
return alloc;
}
void doFree( void* adrs )
{
OSIntrMode nOSIntrMode;
nOSIntrMode = OS_DisableInterrupts( );
OS_Free( adrs );
(void)OS_RestoreInterrupts( nOSIntrMode );
}
void* doMemset( void* adrs, int val, int cnt )
{
return memset( adrs, val, cnt );
}
void* doMemcpy( void* dst, void* src, int cnt )
{
return memcpy( dst, src, cnt );
}
#endif

View File

@ -0,0 +1,320 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file bn_add.c
* @brief BIGNUM addition and subtraction functions
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_ADD
#define SPLIT_BN_UADD
#define SPLIT_BN_USUB
#define SPLIT_BN_SUB
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_ADD
/* r can == a or b */
int BN_add(r, a, b)
BIGNUM *r;
BIGNUM *a;
BIGNUM *b;
{
BIGNUM *tmp;
bn_check_top(a);
bn_check_top(b);
/* a + b a+b
* a + -b a-b
* -a + b b-a
* -a + -b -(a+b)
*/
if (a->neg ^ b->neg)
{
/* only one is negative */
if (a->neg)
{ tmp=a; a=b; b=tmp; }
/* we are now a - b */
if (BN_ucmp(a,b) < 0)
{
if (!BN_usub(r,b,a)) return(0);
r->neg=1;
}
else
{
if (!BN_usub(r,a,b)) return(0);
r->neg=0;
}
return(1);
}
if (a->neg) /* both are neg */
r->neg=1;
else
r->neg=0;
if (!BN_uadd(r,a,b)) return(0);
return(1);
}
#endif
#ifdef SPLIT_BN_UADD
/* unsigned add of b to a, r must be large enough */
int BN_uadd(r,a,b)
BIGNUM *r;
BIGNUM *a;
BIGNUM *b;
{
register int i;
int max,min;
BN_ULONG *ap,*bp,*rp,carry,t1;
BIGNUM *tmp;
bn_check_top(a);
bn_check_top(b);
if (a->top < b->top)
{ tmp=a; a=b; b=tmp; }
max=a->top;
min=b->top;
if (bn_wexpand(r,max+1) == NULL)
return(0);
r->top=max;
ap=a->d;
bp=b->d;
rp=r->d;
carry=0;
carry=bn_add_words(rp,ap,bp,min);
rp+=min;
ap+=min;
bp+=min;
i=min;
if (carry)
{
while (i < max)
{
i++;
t1= *(ap++);
if ((*(rp++)=(t1+1)&BN_MASK2) >= t1)
{
carry=0;
break;
}
}
if ((i >= max) && carry)
{
*(rp++)=1;
r->top++;
}
}
if (rp != ap)
{
for (; i<max; i++)
*(rp++)= *(ap++);
}
/* Memcpy(rp,ap,sizeof(*ap)*(max-i));*/
return(1);
}
#endif
/**
* perform unsigned subtraction of <tt>b</tt> from <tt>a</tt>
* @param r result of subtraction
* @param a pointer to a BIGNUM
* @param b pointer to a BIGNUM
* @pre <tt>a</tt> must be larger than <tt>b</tt>
* @return 1 on success, 0 on failure
* @todo On next IRIX port check the validity of IRIX_CC_BUG.
*/
#ifdef SPLIT_BN_USUB
int BN_usub(r, a, b)
BIGNUM *r;
BIGNUM *a;
BIGNUM *b;
{
int max,min;
register BN_ULONG t1,t2,*ap,*bp,*rp;
int i,carry;
#if defined(IRIX_CC_BUG) && !defined(LINT)
int dummy;
#endif
bn_check_top(a);
bn_check_top(b);
/*
* check for pre-condition violation
*/
if (a->top < b->top)
{
#ifndef NO_ERR
BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3);
#endif
return(0);
}
max=a->top;
min=b->top;
if (bn_wexpand(r,max) == NULL) return(0);
ap=a->d;
bp=b->d;
rp=r->d;
/*
* perform the subtraction and see if we
* have a (final) carry
*/
carry=0;
for (i=0; i<min; i++)
{
t1= *(ap++);
t2= *(bp++);
if (carry)
{
carry=(t1 <= t2);
t1=(t1-t2-1)&BN_MASK2;
}
else
{
carry=(t1 < t2);
t1=(t1-t2)&BN_MASK2;
}
#if defined(IRIX_CC_BUG) && !defined(LINT)
dummy=t1;
#endif
*(rp++)=t1&BN_MASK2;
}
if (carry) /* subtracted */
{
while (i < max)
{
i++;
t1= *(ap++);
t2=(t1-1)&BN_MASK2;
*(rp++)=t2;
if (t1 > t2) break;
}
}
if (rp != ap)
{
#ifdef BN_LIBRARY_SMALL
Memcpy(rp,ap,sizeof(*rp)*(max-i));
#else /* BN_LIBRARY_SMALL */
for (;;)
{
if (i++ >= max) break;
rp[0]=ap[0];
if (i++ >= max) break;
rp[1]=ap[1];
if (i++ >= max) break;
rp[2]=ap[2];
if (i++ >= max) break;
rp[3]=ap[3];
rp+=4;
ap+=4;
}
#endif /* BN_LIBRARY_SMALL */
}
r->top=max;
bn_fix_top(r);
return(1);
}
#endif
#ifdef SPLIT_BN_SUB
int BN_sub(r, a, b)
BIGNUM *r;
BIGNUM *a;
BIGNUM *b;
{
int max;
int add=0,neg=0;
BIGNUM *tmp;
bn_check_top(a);
bn_check_top(b);
/* a - b a-b
* a - -b a+b
* -a - b -(a+b)
* -a - -b b-a
*/
if (a->neg)
{
if (b->neg)
{ tmp=a; a=b; b=tmp; }
else
{ add=1; neg=1; }
}
else
{
if (b->neg) { add=1; neg=0; }
}
if (add)
{
if (!BN_uadd(r,a,b)) return(0);
r->neg=neg;
return(1);
}
/* We are actually doing a - b */
max=(a->top > b->top)?a->top:b->top;
if (bn_wexpand(r,max) == NULL) return(0);
if (BN_ucmp(a,b) < 0)
{
if (!BN_usub(r,b,a)) return(0);
r->neg=1;
}
else
{
if (!BN_usub(r,a,b)) return(0);
r->neg=0;
}
return(1);
}
#endif
#endif

View File

@ -0,0 +1,525 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#ifndef OPT_BN_ASM
#define BN_MUL_ADD_WORDS
#ifndef BN_MUL_WORDS
#define BN_MUL_WORDS
#endif
#ifndef BN_SQR_WORDS
#define BN_SQR_WORDS
#endif
#ifndef BN_ADD_WORDS
#define BN_ADD_WORDS
#endif
#ifndef BN_SUB_WORDS
#define BN_SUB_WORDS
#endif
#endif
#include "bn_lcl.h"
#ifdef BN_LLONG
/*
* bn_mul_add_words
*
* for(i=0;i<num;i++)
* rp[i]+=ap[i]*w (with carry propagation)
*
*/
#ifdef BN_MUL_ADD_WORDS
#if 0
BN_ULONG bn_mul_add_words(rp,ap,num,w)
BN_ULONG *rp,*ap;
int num;
BN_ULONG w;
{
BN_ULONG c1=0;
bn_check_num(num);
if (num <= 0) return(c1);
for (;;)
{
mul_add(rp[0],ap[0],w,c1);
if (--num == 0) break;
ap++;
rp++;
}
return(c1);
}
#endif
BN_ULONG bn_mul_add_words(rp,ap,num,w)
BN_ULONG *rp,*ap;
int num;
BN_ULONG w;
{
BN_ULONG c1=0;
bn_check_num(num);
if (num <= 0) return(c1);
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
{
int i,nn=num;
for (i=num-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,ap[i]);
fprintf(stderr,"*");
fprintf(stderr,BN_HEX_FMT,w);
fprintf(stderr,"+");
for (i=num-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,rp[i]);
#endif
for (;;)
{
mul_add(rp[0],ap[0],w,c1);
if (--num == 0) break;
mul_add(rp[1],ap[1],w,c1);
if (--num == 0) break;
mul_add(rp[2],ap[2],w,c1);
if (--num == 0) break;
mul_add(rp[3],ap[3],w,c1);
if (--num == 0) break;
ap+=4;
rp+=4;
}
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
fprintf(stderr,"-");
fprintf(stderr,BN_HEX_FMT,c1);
for (i=nn-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,rp[i]);
fprintf(stderr,"\n");
}
#endif
return(c1);
}
#endif
#ifdef BN_MUL_WORDS
BN_ULONG bn_mul_words(rp,ap,num,w)
BN_ULONG *rp,*ap;
int num;
BN_ULONG w;
{
BN_ULONG c1=0;
bn_check_num(num);
if (num <= 0) return(c1);
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
{
int i,nn=num;
for (i=num-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,ap[i]);
fprintf(stderr,"*");
fprintf(stderr,BN_HEX_FMT,w);
#endif
for (;;)
{
mul(rp[0],ap[0],w,c1);
if (--num == 0) break;
mul(rp[1],ap[1],w,c1);
if (--num == 0) break;
mul(rp[2],ap[2],w,c1);
if (--num == 0) break;
mul(rp[3],ap[3],w,c1);
if (--num == 0) break;
ap+=4;
rp+=4;
}
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
fprintf(stderr,"-");
fprintf(stderr,BN_HEX_FMT,c1);
for (i=nn-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,rp[i]);
fprintf(stderr,"\n");
}
#endif
return(c1);
}
#endif
#ifdef BN_SQR_WORDS
void bn_sqr_words(r,a,n)
BN_ULONG *r,*a;
int n;
{
bn_check_num(n);
if (n <= 0) return;
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
{
int i,nn=n;
for (i=n-1; i>=0; i--)
{
fprintf(stderr,BN_HEX_FMT,a[i]);
if (i != 0)
fprintf(stderr,"^2*2^%X+",i*2*BN_BITS2);
else
fprintf(stderr,"^2");
}
#endif
for (;;)
{
BN_ULLONG t;
t=(BN_ULLONG)(a[0])*(a[0]);
r[0]=Lw(t); r[1]=Hw(t);
if (--n == 0) break;
t=(BN_ULLONG)(a[1])*(a[1]);
r[2]=Lw(t); r[3]=Hw(t);
if (--n == 0) break;
t=(BN_ULLONG)(a[2])*(a[2]);
r[4]=Lw(t); r[5]=Hw(t);
if (--n == 0) break;
t=(BN_ULLONG)(a[3])*(a[3]);
r[6]=Lw(t); r[7]=Hw(t);
if (--n == 0) break;
a+=4;
r+=8;
}
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
fprintf(stderr,"-");
for (i=nn+nn-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,r[i]);
fprintf(stderr,"\n");
}
#endif
}
#endif
#else
#ifdef BN_MUL_ADD_WORDS
BN_ULONG bn_mul_add_words(rp,ap,num,w)
BN_ULONG *rp,*ap;
int num;
BN_ULONG w;
{
BN_ULONG c=0;
BN_ULONG bl,bh,b_hl;
bn_check_num(num);
if (num <= 0) return((BN_ULONG)0);
bl=LBITS(w);
bh=HBITS(w);
b_hl=bh-bl;
/*
{ int i,nnum=num;
BN_ULONG *rrp=rp;
for (i=num-1; i>=0; i--) printf("%02X",rp[i]);
printf("+");
for (i=num-1; i>=0; i--) printf("%02X",ap[i]);
printf("*%02X - ",w);
*/
for (;;)
{
mul_add(rp[0],ap[0],bl,bh,b_hl,c);
if (--num == 0) break;
mul_add(rp[1],ap[1],bl,bh,b_hl,c);
if (--num == 0) break;
mul_add(rp[2],ap[2],bl,bh,b_hl,c);
if (--num == 0) break;
mul_add(rp[3],ap[3],bl,bh,b_hl,c);
if (--num == 0) break;
ap+=4;
rp+=4;
}
/*
printf("%02X",c);
for (i=nnum-1; i>=0; i--) printf("%02X",rrp[i]);
printf("\n");
}
*/
return(c);
}
#endif
#ifdef BN_MUL_WORDS
BN_ULONG bn_mul_words(rp,ap,num,w)
BN_ULONG *rp,*ap;
int num;
BN_ULONG w;
{
BN_ULONG carry=0;
BN_ULONG bl,bh;
bn_check_num(num);
if (num <= 0) return((BN_ULONG)0);
bl=LBITS(w);
bh=HBITS(w);
for (;;)
{
mul(rp[0],ap[0],bl,bh,carry);
if (--num == 0) break;
mul(rp[1],ap[1],bl,bh,carry);
if (--num == 0) break;
mul(rp[2],ap[2],bl,bh,carry);
if (--num == 0) break;
mul(rp[3],ap[3],bl,bh,carry);
if (--num == 0) break;
ap+=4;
rp+=4;
}
return(carry);
}
#endif
#ifdef BN_SQR_WORDS
void bn_sqr_words(r,a,n)
BN_ULONG *r,*a;
int n;
{
bn_check_num(n);
if (n <= 0) return;
for (;;)
{
sqr64(r[0],r[1],a[0]);
if (--n == 0) break;
sqr64(r[2],r[3],a[1]);
if (--n == 0) break;
sqr64(r[4],r[5],a[2]);
if (--n == 0) break;
sqr64(r[6],r[7],a[3]);
if (--n == 0) break;
a+=4;
r+=8;
}
}
#endif
#endif
#ifdef BN_ADD_WORDS
#ifdef BN_LLONG
BN_ULONG bn_add_words(r,a,b,n)
BN_ULONG *r,*a,*b;
int n;
{
BN_ULLONG ll=0;
bn_check_num(n);
if (n <= 0) return((BN_ULONG)0);
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
{
int i,nn=n;
for (i=n-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,a[i]);
fprintf(stderr,"+");
for (i=n-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,b[i]);
#endif
for (;;)
{
ll+=(BN_ULLONG)a[0]+b[0];
r[0]=(BN_ULONG)ll&BN_MASK2;
ll>>=BN_BITS2;
if (--n <= 0) break;
ll+=(BN_ULLONG)a[1]+b[1];
r[1]=(BN_ULONG)ll&BN_MASK2;
ll>>=BN_BITS2;
if (--n <= 0) break;
ll+=(BN_ULLONG)a[2]+b[2];
r[2]=(BN_ULONG)ll&BN_MASK2;
ll>>=BN_BITS2;
if (--n <= 0) break;
ll+=(BN_ULLONG)a[3]+b[3];
r[3]=(BN_ULONG)ll&BN_MASK2;
ll>>=BN_BITS2;
if (--n <= 0) break;
a+=4;
b+=4;
r+=4;
}
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
fprintf(stderr,"-");
fprintf(stderr,BN_HEX_FMT,(BN_ULONG)ll);
for (i=nn-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,r[i]);
fprintf(stderr,"\n");
}
#endif
return((BN_ULONG)ll);
}
#else
BN_ULONG bn_add_words(r,a,b,n)
BN_ULONG *r,*a,*b;
int n;
{
BN_ULONG c,l,t;
bn_check_num(n);
if (n <= 0) return((BN_ULONG)0);
c=0;
for (;;)
{
t=a[0];
t=(t+c)&BN_MASK2;
c=(t < c);
l=(t+b[0])&BN_MASK2;
c+=(l < t);
r[0]=l;
if (--n <= 0) break;
t=a[1];
t=(t+c)&BN_MASK2;
c=(t < c);
l=(t+b[1])&BN_MASK2;
c+=(l < t);
r[1]=l;
if (--n <= 0) break;
t=a[2];
t=(t+c)&BN_MASK2;
c=(t < c);
l=(t+b[2])&BN_MASK2;
c+=(l < t);
r[2]=l;
if (--n <= 0) break;
t=a[3];
t=(t+c)&BN_MASK2;
c=(t < c);
l=(t+b[3])&BN_MASK2;
c+=(l < t);
r[3]=l;
if (--n <= 0) break;
a+=4;
b+=4;
r+=4;
}
return((BN_ULONG)c);
}
#endif
#endif
#ifdef BN_SUB_WORDS
BN_ULONG bn_sub_words(r,a,b,n)
BN_ULONG *r,*a,*b;
int n;
{
BN_ULONG c,t1,t2;
bn_check_num(n);
if (n <= 0) return((BN_ULONG)0);
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
{
int i,nn=n;
for (i=n-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,a[i]);
fprintf(stderr,"-");
for (i=n-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,b[i]);
#endif
c=0;
for (;;)
{
t1=a[0]; t2=b[0];
r[0]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[1]; t2=b[1];
r[1]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[2]; t2=b[2];
r[2]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[3]; t2=b[3];
r[3]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
a+=4;
b+=4;
r+=4;
}
#if defined(BN_ASM_DEBUG) && !defined(NO_FP_API)
fprintf(stderr,"- ");
if (c) fprintf(stderr,"-");
for (i=nn-1; i>=0; i--)
fprintf(stderr,BN_HEX_FMT,r[i]);
fprintf(stderr,"\n");
}
#endif
return(c);
}
#endif

View File

@ -0,0 +1,450 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MUL_COMBA8
#define SPLIT_BN_MUL_COMBA4
#define SPLIT_BN_SQR_COMBA8
#define SPLIT_BN_SQR_COMBA4
#endif /* NO_SPLIT */
#ifndef OPT_BN_ASM
/* #if 1 */
#ifdef BN_LLONG
#define mul_add_c(a,b,c0,c1,c2) \
t=(BN_ULLONG)a*b; \
t1=(BN_ULONG)Lw(t); \
t2=(BN_ULONG)Hw(t); \
c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define mul_add_c2(a,b,c0,c1,c2) \
t=(BN_ULLONG)a*b; \
tt=(t+t)&BN_MASK; \
if (tt < t) c2++; \
t1=(BN_ULONG)Lw(tt); \
t2=(BN_ULONG)Hw(tt); \
c0=(c0+t1)&BN_MASK2; \
if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define sqr_add_c(a,i,c0,c1,c2) \
t=(BN_ULLONG)a[i]*a[i]; \
t1=(BN_ULONG)Lw(t); \
t2=(BN_ULONG)Hw(t); \
c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define sqr_add_c2(a,i,j,c0,c1,c2) \
mul_add_c2((a)[i],(a)[j],c0,c1,c2)
#else
#define mul_add_c(a,b,c0,c1,c2) \
t1=LBITS(a); t2=HBITS(a); \
bl=LBITS(b); bh=HBITS(b); \
mul64(t1,t2,bl,bh); \
c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define mul_add_c2(a,b,c0,c1,c2) \
t1=LBITS(a); t2=HBITS(a); \
bl=LBITS(b); bh=HBITS(b); \
mul64(t1,t2,bl,bh); \
if (t2 & BN_TBIT) c2++; \
t2=(t2+t2)&BN_MASK2; \
if (t1 & BN_TBIT) t2++; \
t1=(t1+t1)&BN_MASK2; \
c0=(c0+t1)&BN_MASK2; \
if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define sqr_add_c(a,i,c0,c1,c2) \
sqr64(t1,t2,(a)[i]); \
c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
#define sqr_add_c2(a,i,j,c0,c1,c2) \
mul_add_c2((a)[i],(a)[j],c0,c1,c2)
#endif
#if defined(BN_MUL_COMBA)
#ifdef SPLIT_BN_MUL_COMBA8
#undef bn_mul_comba8
void bn_mul_comba8(r,a,b)
BN_ULONG *r,*a,*b;
{
#ifdef BN_LLONG
BN_ULLONG t;
#else
BN_ULONG bl,bh;
#endif
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
mul_add_c(a[0],b[0],c1,c2,c3);
r[0]=c1;
c1=0;
mul_add_c(a[0],b[1],c2,c3,c1);
mul_add_c(a[1],b[0],c2,c3,c1);
r[1]=c2;
c2=0;
mul_add_c(a[2],b[0],c3,c1,c2);
mul_add_c(a[1],b[1],c3,c1,c2);
mul_add_c(a[0],b[2],c3,c1,c2);
r[2]=c3;
c3=0;
mul_add_c(a[0],b[3],c1,c2,c3);
mul_add_c(a[1],b[2],c1,c2,c3);
mul_add_c(a[2],b[1],c1,c2,c3);
mul_add_c(a[3],b[0],c1,c2,c3);
r[3]=c1;
c1=0;
mul_add_c(a[4],b[0],c2,c3,c1);
mul_add_c(a[3],b[1],c2,c3,c1);
mul_add_c(a[2],b[2],c2,c3,c1);
mul_add_c(a[1],b[3],c2,c3,c1);
mul_add_c(a[0],b[4],c2,c3,c1);
r[4]=c2;
c2=0;
mul_add_c(a[0],b[5],c3,c1,c2);
mul_add_c(a[1],b[4],c3,c1,c2);
mul_add_c(a[2],b[3],c3,c1,c2);
mul_add_c(a[3],b[2],c3,c1,c2);
mul_add_c(a[4],b[1],c3,c1,c2);
mul_add_c(a[5],b[0],c3,c1,c2);
r[5]=c3;
c3=0;
mul_add_c(a[6],b[0],c1,c2,c3);
mul_add_c(a[5],b[1],c1,c2,c3);
mul_add_c(a[4],b[2],c1,c2,c3);
mul_add_c(a[3],b[3],c1,c2,c3);
mul_add_c(a[2],b[4],c1,c2,c3);
mul_add_c(a[1],b[5],c1,c2,c3);
mul_add_c(a[0],b[6],c1,c2,c3);
r[6]=c1;
c1=0;
mul_add_c(a[0],b[7],c2,c3,c1);
mul_add_c(a[1],b[6],c2,c3,c1);
mul_add_c(a[2],b[5],c2,c3,c1);
mul_add_c(a[3],b[4],c2,c3,c1);
mul_add_c(a[4],b[3],c2,c3,c1);
mul_add_c(a[5],b[2],c2,c3,c1);
mul_add_c(a[6],b[1],c2,c3,c1);
mul_add_c(a[7],b[0],c2,c3,c1);
r[7]=c2;
c2=0;
mul_add_c(a[7],b[1],c3,c1,c2);
mul_add_c(a[6],b[2],c3,c1,c2);
mul_add_c(a[5],b[3],c3,c1,c2);
mul_add_c(a[4],b[4],c3,c1,c2);
mul_add_c(a[3],b[5],c3,c1,c2);
mul_add_c(a[2],b[6],c3,c1,c2);
mul_add_c(a[1],b[7],c3,c1,c2);
r[8]=c3;
c3=0;
mul_add_c(a[2],b[7],c1,c2,c3);
mul_add_c(a[3],b[6],c1,c2,c3);
mul_add_c(a[4],b[5],c1,c2,c3);
mul_add_c(a[5],b[4],c1,c2,c3);
mul_add_c(a[6],b[3],c1,c2,c3);
mul_add_c(a[7],b[2],c1,c2,c3);
r[9]=c1;
c1=0;
mul_add_c(a[7],b[3],c2,c3,c1);
mul_add_c(a[6],b[4],c2,c3,c1);
mul_add_c(a[5],b[5],c2,c3,c1);
mul_add_c(a[4],b[6],c2,c3,c1);
mul_add_c(a[3],b[7],c2,c3,c1);
r[10]=c2;
c2=0;
mul_add_c(a[4],b[7],c3,c1,c2);
mul_add_c(a[5],b[6],c3,c1,c2);
mul_add_c(a[6],b[5],c3,c1,c2);
mul_add_c(a[7],b[4],c3,c1,c2);
r[11]=c3;
c3=0;
mul_add_c(a[7],b[5],c1,c2,c3);
mul_add_c(a[6],b[6],c1,c2,c3);
mul_add_c(a[5],b[7],c1,c2,c3);
r[12]=c1;
c1=0;
mul_add_c(a[6],b[7],c2,c3,c1);
mul_add_c(a[7],b[6],c2,c3,c1);
r[13]=c2;
c2=0;
mul_add_c(a[7],b[7],c3,c1,c2);
r[14]=c3;
r[15]=c1;
}
#endif
#ifdef SPLIT_BN_MUL_COMBA4
#undef bn_mul_comba4
void bn_mul_comba4(r,a,b)
BN_ULONG *r,*a,*b;
{
#ifdef BN_LLONG
BN_ULLONG t;
#else
BN_ULONG bl,bh;
#endif
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
mul_add_c(a[0],b[0],c1,c2,c3);
r[0]=c1;
c1=0;
mul_add_c(a[0],b[1],c2,c3,c1);
mul_add_c(a[1],b[0],c2,c3,c1);
r[1]=c2;
c2=0;
mul_add_c(a[2],b[0],c3,c1,c2);
mul_add_c(a[1],b[1],c3,c1,c2);
mul_add_c(a[0],b[2],c3,c1,c2);
r[2]=c3;
c3=0;
mul_add_c(a[0],b[3],c1,c2,c3);
mul_add_c(a[1],b[2],c1,c2,c3);
mul_add_c(a[2],b[1],c1,c2,c3);
mul_add_c(a[3],b[0],c1,c2,c3);
r[3]=c1;
c1=0;
mul_add_c(a[3],b[1],c2,c3,c1);
mul_add_c(a[2],b[2],c2,c3,c1);
mul_add_c(a[1],b[3],c2,c3,c1);
r[4]=c2;
c2=0;
mul_add_c(a[2],b[3],c3,c1,c2);
mul_add_c(a[3],b[2],c3,c1,c2);
r[5]=c3;
c3=0;
mul_add_c(a[3],b[3],c1,c2,c3);
r[6]=c1;
r[7]=c2;
}
#endif
#else
#ifdef SPLIT_BN_MUL_COMBA4
#undef bn_mul_comba4
void bn_mul_comba4(r,a,b)
BN_ULONG *r,*a,*b;
{
r[4]=bn_mul_words( &(r[0]),a,4,b[0]);
r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]);
r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]);
r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]);
}
#endif
#ifdef SPLIT_BN_MUL_COMBA8
#undef bn_mul_comba8
void bn_mul_comba8(r,a,b)
BN_ULONG *r,*a,*b;
{
r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]);
r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
}
#endif
#endif /* BN_MUL_COMBA */
#ifdef BN_SQR_COMBA
#ifdef SPLIT_BN_SQR_COMBA8
#undef bn_sqr_comba8
void bn_sqr_comba8(r,a)
BN_ULONG *r,*a;
{
#ifdef BN_LLONG
BN_ULLONG t,tt;
#else
BN_ULONG bl,bh;
#endif
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
sqr_add_c(a,0,c1,c2,c3);
r[0]=c1;
c1=0;
sqr_add_c2(a,1,0,c2,c3,c1);
r[1]=c2;
c2=0;
sqr_add_c(a,1,c3,c1,c2);
sqr_add_c2(a,2,0,c3,c1,c2);
r[2]=c3;
c3=0;
sqr_add_c2(a,3,0,c1,c2,c3);
sqr_add_c2(a,2,1,c1,c2,c3);
r[3]=c1;
c1=0;
sqr_add_c(a,2,c2,c3,c1);
sqr_add_c2(a,3,1,c2,c3,c1);
sqr_add_c2(a,4,0,c2,c3,c1);
r[4]=c2;
c2=0;
sqr_add_c2(a,5,0,c3,c1,c2);
sqr_add_c2(a,4,1,c3,c1,c2);
sqr_add_c2(a,3,2,c3,c1,c2);
r[5]=c3;
c3=0;
sqr_add_c(a,3,c1,c2,c3);
sqr_add_c2(a,4,2,c1,c2,c3);
sqr_add_c2(a,5,1,c1,c2,c3);
sqr_add_c2(a,6,0,c1,c2,c3);
r[6]=c1;
c1=0;
sqr_add_c2(a,7,0,c2,c3,c1);
sqr_add_c2(a,6,1,c2,c3,c1);
sqr_add_c2(a,5,2,c2,c3,c1);
sqr_add_c2(a,4,3,c2,c3,c1);
r[7]=c2;
c2=0;
sqr_add_c(a,4,c3,c1,c2);
sqr_add_c2(a,5,3,c3,c1,c2);
sqr_add_c2(a,6,2,c3,c1,c2);
sqr_add_c2(a,7,1,c3,c1,c2);
r[8]=c3;
c3=0;
sqr_add_c2(a,7,2,c1,c2,c3);
sqr_add_c2(a,6,3,c1,c2,c3);
sqr_add_c2(a,5,4,c1,c2,c3);
r[9]=c1;
c1=0;
sqr_add_c(a,5,c2,c3,c1);
sqr_add_c2(a,6,4,c2,c3,c1);
sqr_add_c2(a,7,3,c2,c3,c1);
r[10]=c2;
c2=0;
sqr_add_c2(a,7,4,c3,c1,c2);
sqr_add_c2(a,6,5,c3,c1,c2);
r[11]=c3;
c3=0;
sqr_add_c(a,6,c1,c2,c3);
sqr_add_c2(a,7,5,c1,c2,c3);
r[12]=c1;
c1=0;
sqr_add_c2(a,7,6,c2,c3,c1);
r[13]=c2;
c2=0;
sqr_add_c(a,7,c3,c1,c2);
r[14]=c3;
r[15]=c1;
}
#endif
#ifdef SPLIT_BN_SQR_COMBA4
#undef bn_sqr_comba4
void bn_sqr_comba4(r,a)
BN_ULONG *r,*a;
{
#ifdef BN_LLONG
BN_ULLONG t,tt;
#else
BN_ULONG bl,bh;
#endif
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
sqr_add_c(a,0,c1,c2,c3);
r[0]=c1;
c1=0;
sqr_add_c2(a,1,0,c2,c3,c1);
r[1]=c2;
c2=0;
sqr_add_c(a,1,c3,c1,c2);
sqr_add_c2(a,2,0,c3,c1,c2);
r[2]=c3;
c3=0;
sqr_add_c2(a,3,0,c1,c2,c3);
sqr_add_c2(a,2,1,c1,c2,c3);
r[3]=c1;
c1=0;
sqr_add_c(a,2,c2,c3,c1);
sqr_add_c2(a,3,1,c2,c3,c1);
r[4]=c2;
c2=0;
sqr_add_c2(a,3,2,c3,c1,c2);
r[5]=c3;
c3=0;
sqr_add_c(a,3,c1,c2,c3);
r[6]=c1;
r[7]=c2;
}
#endif
#else
#ifdef SPLIT_BN_SQR_COMBA4
/* hmm... is it faster just to do a multiply? */
#undef bn_sqr_comba4
void bn_sqr_comba4(r,a)
BN_ULONG *r,*a;
{
BN_ULONG t[8];
bn_sqr_normal(r,a,4,t);
}
#endif
#ifdef SPLIT_BN_SQR_COMBA8
#undef bn_sqr_comba8
void bn_sqr_comba8(r,a)
BN_ULONG *r,*a;
{
BN_ULONG t[16];
bn_sqr_normal(r,a,8,t);
}
#endif
#endif
#endif /* OPT_BN_ASM */
#endif

View File

@ -0,0 +1,381 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file bn_div.c
* @brief Division and modulus functions
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_DIV
#define SPLIT_BN_MOD
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_DIV
/* The old slow way */
#ifdef OLD_BN_DIVISION
int BN_div(dv, rem, m, d,ctx)
BIGNUM *dv;
BIGNUM *rem;
BIGNUM *m;
BIGNUM *d;
BN_CTX *ctx;
{
int i,nm,nd;
BIGNUM *D;
bn_check_top(m);
bn_check_top(d);
if (BN_is_zero(d))
{
#ifndef NO_ERR
BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
#endif
return(0);
}
if (BN_ucmp(m,d) < 0)
{
if (rem != NULL)
{ if (BN_copy(rem,m) == NULL) return(0); }
if (dv != NULL) BN_zero(dv);
return(1);
}
D= &(ctx->bn[ctx->tos]);
if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]);
if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]);
nd=BN_num_bits(d);
nm=BN_num_bits(m);
if (BN_copy(D,d) == NULL) return(0);
if (BN_copy(rem,m) == NULL) return(0);
/* The next 2 are needed so we can do a dv->d[0]|=1 later
* since BN_lshift1 will only work once there is a value
*/
BN_zero(dv);
bn_wexpand(dv,1);
dv->top=1;
if (!BN_lshift(D,D,nm-nd)) return(0);
for (i=nm-nd; i>=0; i--)
{
if (!BN_lshift1(dv,dv)) return(0);
if (BN_ucmp(rem,D) >= 0)
{
dv->d[0]|=1;
if (!BN_usub(rem,rem,D)) return(0);
}
/* CAN IMPROVE (and have now :=) */
if (!BN_rshift1(D,D)) return(0);
}
rem->neg=BN_is_zero(rem)?0:m->neg;
dv->neg=m->neg^d->neg;
return(1);
}
#else
/**
* Performs Big number division
*
* @param dv [In] division
* @param rm [Out] remainder
* @param num [In] number
* @param divisor [In] divisor
* @param ctx [In] Temporary data storage
*
* @todo add more comments to this function
*/
int BN_div(BIGNUM *dv, BIGNUM *rm, BIGNUM *num, BIGNUM *divisor, BN_CTX *ctx)
{
int norm_shift,i,j,loop;
BIGNUM *tmp,wnum,*snum,*sdiv,*res;
BN_ULONG *resp,*wnump;
BN_ULONG d0,d1;
int num_n,div_n;
bn_check_top(num);
bn_check_top(divisor);
if (BN_is_zero(divisor))
{
#ifndef NO_ERR
BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
#endif
return(0);
}
if (BN_ucmp(num,divisor) < 0)
{
if (rm != NULL)
{ if (BN_copy(rm,num) == NULL) return(0); }
if (dv != NULL) (void)BN_zero(dv);
return(1);
}
tmp= &(ctx->bn[ctx->tos]);
tmp->neg=0;
snum= &(ctx->bn[ctx->tos+1]);
sdiv= &(ctx->bn[ctx->tos+2]);
if (dv == NULL)
res= &(ctx->bn[ctx->tos+3]);
else res=dv;
/* First we normalise the numbers */
norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
if (!BN_lshift(sdiv,divisor,norm_shift)) return(0);
sdiv->neg=0;
norm_shift+=BN_BITS2;
if (!BN_lshift(snum,num,norm_shift)) return(0);
snum->neg=0;
div_n=sdiv->top;
num_n=snum->top;
loop=num_n-div_n;
/* Lets setup a 'window' into snum
* This is the part that corresponds to the current
* 'area' being divided */
BN_init(&wnum);
wnum.d= &(snum->d[loop]);
wnum.top= div_n;
wnum.max= snum->max+1; /* a bit of a lie */
/* Get the top 2 words of sdiv */
/* i=sdiv->top; */
d0=sdiv->d[div_n-1];
d1=(div_n == 1)?0:sdiv->d[div_n-2];
/* pointer to the 'top' of snum */
wnump= &(snum->d[num_n-1]);
/* Setup to 'res' */
if (!bn_wexpand(res,(loop+1))) goto err;
res->neg= (num->neg^divisor->neg);
res->top=loop;
resp= &(res->d[loop-1]);
/* space for temp */
if (!bn_wexpand(tmp,(div_n+1))) goto err;
if (BN_ucmp(&wnum,sdiv) >= 0)
{
if (!BN_usub(&wnum,&wnum,sdiv)) goto err;
*resp=1;
res->d[res->top-1]=1;
}
else
res->top--;
resp--;
for (i=0; i<loop-1; i++)
{
BN_ULONG q,n0,n1;
BN_ULONG l0;
wnum.d--; wnum.top++;
n0=wnump[0];
n1=wnump[-1];
if (n0 == d0)
q=BN_MASK2;
else
q=bn_div_words(n0,n1,d0);
{
#ifdef BN_LLONG
BN_ULLONG t1,t2,rem;
t1=((((BN_ULLONG)n0)<<BN_BITS2)|n1)&BN_MASK;
for (;;)
{
t2=((BN_ULLONG)d1*q)&BN_MASK;
rem=(t1-(BN_ULLONG)q*d0)&BN_MASK;
if ((rem>>BN_BITS2) ||
(t2 <= ((BN_ULLONG)(rem<<BN_BITS2)+wnump[-2])))
break;
q--;
}
#else
BN_ULONG t1l,t1h,t2l,t2h,t3l,t3h,ql,qh,t3t;
t1h=n0;
t1l=n1;
for (;;)
{
t2l=LBITS(d1); t2h=HBITS(d1);
ql =LBITS(q); qh =HBITS(q);
mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
t3t=LBITS(d0); t3h=HBITS(d0);
mul64(t3t,t3h,ql,qh); /* t3=t1-(BN_ULLONG)q*d0; */
t3l=(t1l-t3t)&BN_MASK2;
if (t3l > t1l) t3h++;
t3h=(t1h-t3h)&BN_MASK2;
/*if ((t3>>BN_BITS2) ||
(t2 <= ((t3<<BN_BITS2)+wnump[-2])))
break; */
if (t3h) break;
if (t2h < t3l) break;
if ((t2h == t3l) && (t2l <= wnump[-2])) break;
q--;
}
#endif
}
l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
tmp->d[div_n]=l0;
for (j=div_n+1; j>0; j--)
if (tmp->d[j-1]) break;
tmp->top=j;
j=wnum.top;
#ifdef BN_DEBUG
/* Sometimes this is 0 now (wnum.top is not).
* We need to look at this some time, I am quite
* sure it has no affect.
*/
bn_fix_top(&wnum);
#endif
(void)BN_sub(&wnum,&wnum,tmp);
snum->top=snum->top+wnum.top-j;
if (wnum.neg)
{
q--;
j=wnum.top;
(void)BN_add(&wnum,&wnum,sdiv);
snum->top+=wnum.top-j;
}
*(resp--)=q;
wnump--;
}
bn_fix_top(snum);
if (rm != NULL)
{
i=num->neg; /* just in case num == rm */
if (BN_rshift(rm,snum,norm_shift) == 0)
return(0);
rm->neg=i;
}
return(1);
err:
return(0);
}
#endif
#endif
#ifdef SPLIT_BN_MOD
/**
* Calculate the remainder where rem = m mod d
*
* @param rem [Out] Modulus result
* @param m [In] Base value
* @param d [In] Divisor
* @param ctx [In] BN_CTX for data space
*
* @pre variables are initialised and valid
* @post rem contained modulus
*
* @retval 1 success
* @retval 0 failure
*
* @note when BN_LIBRARY_SMALL define uses following algorithm
* otherwise calls through to BN_div
*
* @note m < d rem = m
* (length m = length of d) and (m > d) , rem = m - d
* alg otherwise
* let rem = m
* loop while rem > d
* let dv = shift left d, n bits to = length rem
* if dv > rem
* let dv = shift left d, n - 1 bits ( = length rem - 1)
* end if
* let rem = rem - dv;
* end loop
*
* @relates BN_div
*/
int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx)
{
#ifdef BN_LIBRARY_SMALL
int nm,nd;
BIGNUM *dv, *dv2;
/* if m < d , mod = m */
if (BN_ucmp(m,d) < 0)
return((BN_copy(rem,m) == NULL)?0:1);
dv= &(ctx->bn[ctx->tos]);
dv2 = &(ctx->bn[ctx->tos+1]);
nm=BN_num_bits(m);
nd=BN_num_bits(d);
/* if bits m = bits d and m >= d (from above)
* rem = m - d
*/
if(nm == nd)
{
BN_usub(rem, m, d);
goto end;
}
if (BN_copy(rem, m) == NULL)
{
return 0;
}
/* while the rem > d */
while(BN_ucmp(rem,d) > 0)
{
nm=BN_num_bits(rem);
if(!BN_lshift(dv2,d,nm-nd))
{
return(0);
}
if(BN_ucmp(dv2, rem) >0)
{
if(!BN_lshift(dv2,d,nm-nd-1))
{
return(0);
}
}
BN_usub(rem,rem,dv2);
}
end:
return(1);
#else
return(BN_div(NULL,rem,m,d,ctx));
#endif
}
#endif
#endif

View File

@ -0,0 +1,453 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
const static unsigned char p2 []={0,8,1,1,1,1,1,0,0,0};
const static unsigned char p4 []={0,8,1,1,1,4,1,0,0,0};
const static unsigned char p16[]={0,8,1,1,1,16,1,0,0,0};
/* The following defines allow for redefinition of the window size
* of the exponent string at compile time, this affects the size
* of temporary data required in montgomery operations.
* Larger window sizes have more memory and are slightly faster
*/
#ifndef MAX_WIN_SIZE
#define MAX_WIN_SIZE 5
#endif
#if (MAX_WIN_SIZE == 6)
#define MAX_NUM_SIZE 16
#endif
#if (MAX_WIN_SIZE == 5)
#define MAX_NUM_SIZE 16
#endif
#if (MAX_WIN_SIZE == 4)
#define MAX_NUM_SIZE 8
#endif
#if (MAX_WIN_SIZE == 3)
#define MAX_NUM_SIZE 4
#endif
#ifndef MAX_NUM_SIZE
#define MAX_NUM_SIZE 16
#endif
/* This table is used to calculate how far to shift a window to find
* the next 1 bit within the window, for a given window size
* Comment next to each value represents window size, value of the window
* and the number of shifts to find the next 1 bit.
* where the value of the window is 0, the shift is the size of the window
* and thus may not necessary yield a 1 bit, but refreshes the window
*/
const static unsigned char shift[64]=
{6, /* window 6, bits 000000, shift 6 */
0, /* 6, bits 000001, shift 0 */
1, /* 6, bits 000010, shift 1 */
0, /* 6, bits 000011, shift 0 */
2, /* 6, bits 000100, shift 2 */
0, /* 6, bits 000101, shift 0 */
1, /* 6, bits 000110, shift 1 */
0, /* 6, bits 000111, shift 0 */
3, /* 6, bits 001000, shift 3 */
0, /* 6, bits 001001, shift 0 */
1, /* 6, bits 001010, shift 1 */
0, /* 6, bits 001011, shift 0 */
2, /* 6, bits 001100, shift 2 */
0, /* 6, bits 001101, shift 0 */
1, /* 6, bits 001110, shift 1 */
0, /* 6, bits 001111, shift 0 */
4, /* 6, bits 010000, shift 4 */
0, /* 6, bits 010001, shift 0 */
1, /* 6, bits 010010, shift 1 */
0, /* 6, bits 010011, shift 0 */
2, /* 6, bits 010100, shift 2 */
0, /* 6, bits 010101, shift 0 */
1, /* 6, bits 010110, shift 1 */
0, /* 6, bits 010111, shift 0 */
3, /* 6, bits 011000, shift 3 */
0, /* 6, bits 011001, shift 0 */
1, /* 6, bits 011010, shift 1 */
0, /* 6, bits 011011, shift 0 */
2, /* 6, bits 011100, shift 2 */
0, /* 6, bits 011101, shift 0 */
1, /* 6, bits 011110, shift 1 */
0, /* 6, bits 011111, shift 0 */
5, /* 6, bits 100000, shift 5 */
/* also window 5, bits 00000, shift 5 */
0, /* 5 ,bits 00001, shift 0 */
1, /* 5 ,bits 00010, shift 1 */
0, /* 5 ,bits 00011, shift 0 */
2, /* 5 ,bits 00100, shift 2 */
0, /* 5 ,bits 00101, shift 0 */
1, /* 5 ,bits 00110, shift 1 */
0, /* 5 ,bits 00111, shift 0 */
3, /* 5 ,bits 01000, shift 3 */
0, /* 5 ,bits 01001, shift 0 */
1, /* 5 ,bits 01010, shift 1 */
0, /* 5 ,bits 01011, shift 0 */
2, /* 5 ,bits 01100, shift 2 */
0, /* 5 ,bits 01101, shift 0 */
1, /* 5 ,bits 01110, shift 1 */
0, /* 5 ,bits 01111, shift 0 */
4, /* 5 ,bits 10000, shift 1 */
/* also window 4, bits 0000, shift 4 */
0, /* 4 ,bits 0001, shift 0 */
1, /* 4 ,bits 0010, shift 1 */
0, /* 4 ,bits 0011, shift 0 */
2, /* 4 ,bits 0100, shift 2 */
0, /* 4 ,bits 0101, shift 0 */
1, /* 4 ,bits 0110, shift 1 */
0, /* 4 ,bits 0111, shift 0 */
3, /* 4 ,bits 1000, shift 3 */
/* also window 3, bits 000, shift 3 */
0, /* 3 ,bits 001, shift 0 */
1, /* 3 ,bits 010, shift 1 */
0, /* 3 ,bits 011, shift 0 */
2, /* 3 ,bits 100, shift 2 */
0, /* 3 ,bits 101, shift 0 */
1, /* 3 ,bits 110, shift 1 */
0 /* 3 ,bits 111, shift 0 */
};
/* This table defines the starting point in the shift table for
* a particular window size
*/
const static unsigned char *shift_val[7]=
{
&(shift[63]), /* window 0 - unused */
&(shift[62]), /* window 1 */
&(shift[60]), /* window 2 - unused */
&(shift[56]), /* window 3 */
&(shift[48]), /* window 4 */
&(shift[32]), /* window 5 */
&(shift[ 0]), /* window 6 - unused */
};
/**
* Calculates a Montgomery exponent string.
*
* For a supplied exponent p, generate an exponent string strp, which
* defines in pairs the number of multiplies and square operations
* required by a particular bit pattern, commonly used exponents
* 3, 11 and F4 have predefined constant string values, the rest
* are calculated into a cast unsigned char * array via the data
* pointer of a BIGNUM taken from the BN_CTX stack of BIGNUMs
*
* @param p [In] Exponent
* @param strp [Out] Exponent string result
* @param flags [In] Unused
* @param ctx [In] Temporary data storage
*
* @pre p, and ctx are initialised and valid
* @post strp points to required exponent string
*
* @notes String length value in strp[2] is invalid for strings
* greater than length 255
* string terminates with pattern, 0, 0 this should be
* used in accurately determining the length of a returned
* string strp.
*
* @note strings with value sqr = 255, mul = 0, sqr value should be
* treated as value 256, and added to the next sqr value, this
* is used by exponent strings where more then 256 contiguous
* zero bits are in the exponent bit representation.
*
* @note code contains conditional compilation of code dependent on
* the OS int/long sizes
*/
int BN_gen_exp_bits(p,strp,flags,ctx)
BIGNUM *p;
unsigned char **strp;
int flags;
BN_CTX *ctx;
{
int bits,i,j,window,num;
unsigned char *str=NULL;
BIGNUM *tmp;
flags=flags;
bits=p->top*BN_BITS2;
tmp=&(ctx->bn[ctx->tos]);
if (p->top == 0)
return(0);
#if (BN_BITS2 > 17)
if (p->top == 1)
#else
if (bits <= 32)
#endif
{
#if (BN_BITS2 > 17)
if ((p->top == 1) && (p->d[0] == 0x10001))
str=(unsigned char *)p16;
#endif
#if (16 >= BN_BITS2) && (BN_BITS > 8)
if ( (p->top == 2) &&
(p->d[0] == 0x0001) &&
(p->d[1] == 0x0001))
str=(unsigned char *)p16;
#endif
#if (8 >= BN_BITS)
if ( (p->top == 3) &&
(p->d[0] == 0x01) &&
(p->d[1] == 0x00) &&
(p->d[2] == 0x01))
str=(unsigned char *)p16;
#endif
else if ((p->d[0] == 0x11) && (p->top == 1))
str=(unsigned char *)p4;
else if ((p->d[0] == 0x3) && (p->top == 1))
str=(unsigned char *)p2;
window=1;
num=1;
i=BN_BITS2;
}
else if (bits >= 256)
{
window=MAX_WIN_SIZE; /* max size of window */
num=MAX_NUM_SIZE;
i=(BN_BITS2+(MAX_WIN_SIZE -1))/MAX_WIN_SIZE;
}
else if (bits >= 128)
{
window=4;
num=8;
i=(BN_BITS2+3)/4;
}
else /* 128 to 33 */
{
window=3;
num=4;
i=(BN_BITS2+2)/3;
}
/* Number of tmp words */
j=(p->top*i*2+BN_BYTES-1+4)/BN_BYTES;
if (str == NULL)
{
if (!bn_wexpand(tmp,j))
return(0);
str=(unsigned char *)tmp->d;
i=BN_gen_exp_string(&(str[4]),p,window);
i+=2;
str[0]=(unsigned char)((i>>8)&0xff);
str[1]=(unsigned char)((i )&0xff);
str[2]=(unsigned char)window;
str[3]=(unsigned char)num;
}
else
{
i=8;
}
*strp=str;
return(i+2);
}
/**
* Generates the Montgomery exponent string.
*
* This function is used to generate an 'exponent string'
* which is an array of bytes that encode how to perform the steps in
* the a^p%m operation.
*
* @param str [Out] Containing the generated string
* @param p [In] Exponent to generate the string for
* @param bits [In] Size of the window for shifting the values of the BIGNUM
*
* @pre p is initialised and value BIGNUM, bits is not 0
* @post str points to generated exponent string
*
* @note str is cast assigned the data of a BIGNUM allocated and
* expanded from the BN_CTX of the calling function BN_gen_exp_bits
* it does not need to be de-allocated
*
* @note string consisted of unsigned char pairs and 4 byte init
* pairs are sqr count and multiply, where strings are greater
* than 256 bit, length in position str[2] is invalid
*
* @note strings with value sqr = 255, mul = 0, sqr value should be
* treated as value 256, and added to the next sqr value, this
* is used by exponent strings where more then 256 contiguous
* zero bits are in the exponent bit representation.
*
*/
int BN_gen_exp_string(str,p,bits)
unsigned char *str;
BIGNUM *p;
int bits;
{
unsigned char *sp;
unsigned int mask;
const unsigned char *shift;
BN_ULONG w,wh,wl,*d;
unsigned int i,mul,sqr,t,s,ss;
int top;
if (bits > 6) bits=6;
shift= shift_val[bits];
/* This is the mask for the bits we wish to operate on */
mask=(unsigned int)( (1<<bits)-1 );
ss=0;
sp= &(str[((p->top*BN_BITS2+bits-1)/bits)*2+2]);
*sp-- = 0;
*sp-- = 0;
top=p->top; /* Total words we will shift in */
d=p->d;
w=wl= *d++;
if (top <= 1)
wh=0;
else
wh= *d++;
sqr=0;
i=0;
for (;;)
{
/* t will contain how far we need to shift to set a 1
* in the bottom bit. */
for (;;)
{
t=w&mask; /* retrieve our window */
s=shift[t]; /* get the shift value for the window */
if (s == 0) break; /* no shift write out the vals */
sqr+=s; /* add the shifted zero count to sqr */
ss+=s; /* ss is total shift for wl */
if (ss >= BN_BITS2) /* we have shifted > word len */
{
if (top <= 1) break; /* no more to do */
top--; /* dec the count */
wl=wh; /* copy the next word */
/* load the word after or 0 if no more */
wh=(top <= 1)?0:(*d++);
/* adjust our shift by len of word */
ss-=BN_BITS2;
}
/* reset our window word w */
if (ss == 0)
w=wl;
else
w=(wl>>ss)|(wh<<(BN_BITS2-ss));
}
/* At this point we have the 0th bit set */
mul=t;
if (t == 0) break; /* we have reached the end of p */
/* write out sqr/mul pair */
*sp-- = (unsigned char)(sqr & 0xff);
*sp-- = (unsigned char)(mul & 0xff);
if(sqr >= 256) /* check whether sqr exceeds max uchar */
{
/* output the expanded list of to allow for this
* and numbers will require to be added together
* at interpret time
*/
while(sqr >= 256)
{
*sp-- = 255;
*sp-- = 0; /* mul is never zero normally */
sqr-= 256;
}
}
sqr=(unsigned int)bits; /* set sqr to be the window size */
ss+=bits; /* ss is total shift for wl */
if (ss >= BN_BITS2) /* adjust window words w,wl, wh again */
{
if (top <= 1) break;
top--;
wl=wh;
wh=(top <= 1)?0:(*(d++));
ss-=BN_BITS2;
}
if (ss == 0)
w=wl;
else
w=(wl>>ss)|(wh<<(BN_BITS2-ss));
}
sp++;
i=2;
/* reverse the string from the top of the exponent string
* and copy to the bottom, allocated exponent string is 2 * max length
* expected for exponent string
*/
while (sp[0] != 0 || sp[1] != 0)
{
str[0]=sp[0];
str[1]=sp[1];
str+=2;
sp+=2;
i+=2;
}
str[0]=0;
str[1]=0;
return( (int)i );
}
#ifdef MAIN
main()
{
BIGNUM p;
unsigned char buf[512],*pp;
int i;
BN_init(&p);
BN_rand(&p,33,1,0);
#ifndef NO_FP_API
BN_print_fp(stdout,&p); fprintf(stdout,"\n");
#endif
BN_rand(&p,512,1,1);
#ifndef NO_FP_API
BN_print_fp(stdout,&p); fprintf(stdout,"\n");
#endif
for (i=0; i<10000; i++)
BN_gen_exp_string(buf,&p,5);
#if 0
BN_gen_exp_string(buf,&p,3);
pp=buf;
for (;;)
{
printf("mul %d sqr %d\n",pp[0],pp[1]);
if (pp[1] == 0) break;
pp+=2;
}
#endif
}
#endif

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MOD_EXP_ORIG
#define SPLIT_BN_MOD_EXP
#endif /* NO_SPLIT */
#define TABLE_SIZE 16
#ifdef SPLIT_BN_MOD_EXP_ORIG
#if 0
/* this one works - simple but works */
int BN_mod_exp_orig(r,a,p,m,ctx)
BIGNUM *r,*a,*p,*m;
BN_CTX *ctx;
{
int i,bits,ret=0;
BIGNUM *v,*tmp;
v= &(ctx->bn[ctx->tos++]);
tmp= &(ctx->bn[ctx->tos++]);
if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p);
if (BN_is_odd(p))
{ if (BN_copy(r,a) == NULL) goto err; }
else { if (!BN_one(r)) goto err; }
for (i=1; i<bits; i++)
{
if (!BN_sqr(tmp,v,ctx)) goto err;
if (!BN_mod(v,tmp,m,ctx)) goto err;
if (BN_is_bit_set(p,i))
{
if (!BN_mul(tmp,r,v,ctx)) goto err;
if (!BN_mod(r,tmp,m,ctx)) goto err;
}
}
ret=1;
err:
ctx->tos-=2;
return(ret);
}
#endif
/* this one works - simple but works */
int BN_exp(r,a,p,ctx)
BIGNUM *r,*a,*p;
BN_CTX *ctx;
{
int i,bits,ret=0,tos;
BIGNUM *v,*rr;
bn_check_top(a);
bn_check_top(p);
tos=ctx->tos;
v= &(ctx->bn[ctx->tos++]);
if ((r == a) || (r == p))
rr= &(ctx->bn[ctx->tos++]);
else
rr=r;
if (BN_copy(v,a) == NULL) goto err;
bits=BN_num_bits(p);
if (BN_is_odd(p))
{ if (BN_copy(rr,a) == NULL) goto err; }
else { if (!BN_one(rr)) goto err; }
for (i=1; i<bits; i++)
{
if (!BN_sqr(v,v,ctx)) goto err;
if (BN_is_bit_set(p,i))
{
if (!BN_mul(rr,rr,v,ctx)) goto err;
}
}
ret=1;
err:
ctx->tos=tos;
if (r != rr) (void)BN_copy(r,rr);
return(ret);
}
#endif
#ifdef SPLIT_BN_MOD_EXP
/**
* Perform mod exp on BIGNUM
* @param r Pointer to return value BIGNUM
* @param a Pointer to data value BIGNUM
* @param p Pointer to Public exponent BIGNUM
* @param m Pointer to modulus BIGNUM
* @param ctx Pointer to BN_CTX
* @return 0 success
* @pre BIGNUMs a, p, m and BN_CTX ctx exist and are valid
* @post BIGNUM r points to evaluated mod_exp
* @note BN_mod_exp_mont is only available if library compiled
* with define BN_MONT_MUL, and will only be used to compute
* mod_exp operation where the modulus m is odd.
* BN_mod_exp_recp is only available if library is compiled
* with define RECP_MUL_MOD.
* BN_mod_exp_simple is the default method, not available if
* library is compiled with define RECP_MUL_MOD.
* if BN_mod_exp_mont is available, which ever of BN_mod_exp_simple
* or BN_mod_exp_recp is available will only be used for even
* modulus m values.
* @relates BN_mod_exp_mont
* @relates BN_mod_exp_recp
* @relates BN_mod_exp_simple
*/
int BN_mod_exp(r,a,p,m,ctx)
BIGNUM *r;
BIGNUM *a;
BIGNUM *p;
BIGNUM *m;
BN_CTX *ctx;
{
int ret;
bn_check_top(a);
bn_check_top(p);
bn_check_top(m);
#ifdef MONT_MUL_MOD
if (BN_is_odd(m))
{ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }
else
#endif
#ifdef RECP_MUL_MOD
{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
#else
{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }
#endif
return(ret);
}
#endif
#endif

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
/* rp has w words, the top w words are 0 */
void bn_from_montgomery_words(ret,a,np,w,n0)
BN_ULONG *ret;
BN_ULONG *a;
BN_ULONG *np;
int w;
BN_ULONG n0;
{
BN_ULONG v0,v1,*ap,*wap;
int i;
v1=0;
ap=a;
wap= &(a[w]);
/* Consider putting this loop in ASM */
for (i=0; i<w; i++)
{
v0=bn_mul_add_words(ap,np,w,((*ap)*n0)&BN_MASK2);
v0=(v1+v0)&BN_MASK2;
v1= (BN_ULONG)( (v0 < v1)?1:0 );
if (((*wap= *wap+v0)&BN_MASK2) < v0) v1++;
ap++; wap++;
}
/* ap is now wap (&a[w]) */
i=w-1;
if (v1 == 0)
{
if (ap[i] == np[i]) /* GTCHECK */
{
/* i=w-1 */
for (; i>0; i--)
if (ap[i] != np[i]) break;
}
v1=(ap[i] >= np[i]);
}
if (v1)
(void)bn_sub_words(ret,ap,np,w);
else
{
#if 0 /* Alpha does not like Memcpy */
Memcpy(ret,ap,sizeof(BN_ULONG)*w);
#else
for (i=0; i<w; i++)
ret[i]=ap[i];
#endif
}
}

View File

@ -0,0 +1,245 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#ifndef NOPROTO
BIGNUM *bn_euclid(BIGNUM *a, BIGNUM *b);
#else
BIGNUM *bn_euclid();
#endif
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_GCD
#define SPLIT_BN_MOD_INVERSE
#define SPLIT_BN_MOD_INVERSE_WORD
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_GCD
int BN_gcd(r,in_a,in_b,ctx)
BIGNUM *r,*in_a,*in_b;
BN_CTX *ctx;
{
BIGNUM *a,*b,*t;
int ret=0;
bn_check_top(in_a);
bn_check_top(in_b);
a= &(ctx->bn[ctx->tos]);
b= &(ctx->bn[ctx->tos+1]);
if (BN_copy(a,in_a) == NULL) goto err;
if (BN_copy(b,in_b) == NULL) goto err;
if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; }
t=bn_euclid(a,b);
if (t == NULL) goto err;
if (BN_copy(r,t) == NULL) goto err;
ret=1;
err:
return(ret);
}
BIGNUM *bn_euclid(a,b)
BIGNUM *a,*b;
{
BIGNUM *t;
int shifts=0;
bn_check_top(a);
bn_check_top(b);
for (;;)
{
if (BN_is_zero(b))
break;
if (BN_is_odd(a))
{
if (BN_is_odd(b))
{
if (!BN_sub(a,a,b)) goto err;
if (!BN_rshift1(a,a)) goto err;
if (BN_cmp(a,b) < 0)
{ t=a; a=b; b=t; }
}
else /* a odd - b even */
{
if (!BN_rshift1(b,b)) goto err;
if (BN_cmp(a,b) < 0)
{ t=a; a=b; b=t; }
}
}
else /* a is even */
{
if (BN_is_odd(b))
{
if (!BN_rshift1(a,a)) goto err;
if (BN_cmp(a,b) < 0)
{ t=a; a=b; b=t; }
}
else /* a even - b even */
{
if (!BN_rshift1(a,a)) goto err;
if (!BN_rshift1(b,b)) goto err;
shifts++;
}
}
}
if (shifts)
{
if (!BN_lshift(a,a,shifts)) goto err;
}
return(a);
err:
return(NULL);
}
#endif
#ifdef SPLIT_BN_MOD_INVERSE
/* solves ax == 1 (mod n) */
BIGNUM *BN_mod_inverse(in, a, n, ctx)
BIGNUM *in;
BIGNUM *a;
BIGNUM *n;
BN_CTX *ctx;
{
BIGNUM *A,*B,*X,*Y,*M,*D,*R;
BIGNUM *T,*ret=NULL;
int sign;
bn_check_top(a);
bn_check_top(n);
A= &(ctx->bn[ctx->tos]);
B= &(ctx->bn[ctx->tos+1]);
X= &(ctx->bn[ctx->tos+2]);
D= &(ctx->bn[ctx->tos+3]);
M= &(ctx->bn[ctx->tos+4]);
Y= &(ctx->bn[ctx->tos+5]);
ctx->tos+=6;
if (in == NULL)
R=BN_new();
else
R=in;
if (R == NULL) goto err;
(void)BN_zero(X);
(void)BN_one(Y);
if (BN_copy(A,a) == NULL) goto err;
if (BN_copy(B,n) == NULL) goto err;
sign=1;
while (!BN_is_zero(B))
{
if (!BN_div(D,M,A,B,ctx)) goto err;
T=A;
A=B;
B=M;
/* T has a struct, M does not */
if (!BN_mul(T,D,X,ctx)) goto err;
if (!BN_add(T,T,Y)) goto err;
M=Y;
Y=X;
X=T;
sign= -sign;
}
if (sign < 0)
{
if (!BN_sub(Y,n,Y)) goto err;
}
if (BN_is_one(A))
{ if (!BN_mod(R,Y,n,ctx)) goto err; }
else
{
#ifndef NO_ERR
BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
#endif
goto err;
}
ret=R;
err:
if ((ret == NULL) && (in == NULL)) BN_free(R);
ctx->tos-=6;
return(ret);
}
#endif
#ifdef SPLIT_BN_MOD_INVERSE_WORD
/* solves 1 == (ret*(1<<BN_BITS2)) mod n */
BN_ULONG BN_mod_inverse_word(n)
BN_ULONG n;
{
BN_ULONG A,B,X,Y,M,D,R;
BN_ULONG T;
int sign;
X=0;
Y=1;
A=0; /* 1 00000000 */
B=n;
sign=1;
T=((BN_ULONG)0-B)&BN_MASK2;
D=T/B+1;
M=T%B;
T=A; A=B; B=M;
/* T=D*X; X == 0; so leave out */
T=Y;
M=Y; Y=X; X=T;
sign= -sign;
while (B != 0)
{
D=A/B;
M=A%B;
T=D*X+Y;
Y=X; X=T;
A=B; B=M;
sign= -sign;
}
if (sign < 0)
Y=(n-Y)&BN_MASK2;
if (A == 1)
R=Y%n;
else
R=0;
return(R);
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_LSHIFT1
#define SPLIT_BN_LSHIFT
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_LSHIFT1
#ifdef SMALL_CODE_SIZE
int BN_lshift1(r, a)
BIGNUM *r,*a;
{
return(BN_lshift(r, a, 1));
}
#else
int BN_lshift1(r, a)
BIGNUM *r;
BIGNUM *a;
{
register BN_ULONG *ap,*rp,t,c;
int i;
bn_check_top(a);
if (r != a)
{
if (bn_wexpand(r,a->top+1) == NULL) return(0);
r->neg=a->neg;
r->top=a->top;
}
else
{
if (bn_wexpand(r,a->top+1) == NULL) return(0);
}
ap=a->d;
rp=r->d;
c=0;
for (i=0; i<a->top; i++)
{
t= *(ap++);
*(rp++)=((t<<1L)|c)&BN_MASK2;
c=(t & BN_TBIT)?1:0;
}
if (c)
{
*rp=1;
r->top++;
}
return(1);
}
#endif
#endif
#ifdef SPLIT_BN_LSHIFT
int BN_lshift(r, a, n)
BIGNUM *r;
BIGNUM *a;
int n;
{
int i,nw,lb,rb;
BN_ULONG *t,*f;
BN_ULONG l;
bn_check_top(a);
#ifndef SMALL_CODE_SIZE
if (n == 1) return(BN_lshift1(r,a));
#endif
if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0);
r->neg=a->neg;
nw=n/BN_BITS2;
lb=n%BN_BITS2;
rb=BN_BITS2-lb;
f=a->d;
t=r->d;
t[a->top+nw]=0;
if (lb == 0)
for (i=a->top-1; i>=0; i--)
t[nw+i]=f[i];
else
for (i=a->top-1; i>=0; i--)
{
l=f[i];
t[nw+i+1]|=(l>>rb)&BN_MASK2;
t[nw+i]=(l<<lb)&BN_MASK2;
}
(void)Memset(t,0,nw*sizeof(t[0]));
/* for (i=0; i<nw; i++)
t[i]=0;*/
r->top=a->top+nw+1;
bn_fix_top(r);
return(1);
}
#endif
#endif

View File

@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#if 0 //RSA
#include <stdio.h>
#endif
#include "bn_lcl.h"
/* #ifdef MONT_MUL_MOD */
/**
* Generic form of Montgomery Exponentiation, can be called directly
* out side of a BN_ME_METH
*
* @param rr_in BIGNUM pointer for result
* @param a_in BIGNUM pointer for base
* @param p BIGNUM pointer to the exponent
* @param m BIGNUM pointer to the modulus
* @param ctx BN_CTX pointer for temp values are argument storage
* @param in_mont BN_MONT_CTX pointer to structure of montgomery values
*
* @pre arguments are all initialised and not NULL or zero
* @post rr_in contains evaluated result
*
* @note
*/
int BN_mod_exp_mont(rr_in,a_in,p,m,ctx,in_mont)
BIGNUM *rr_in;
BIGNUM *a_in;
BIGNUM *p;
BIGNUM *m;
BN_CTX *ctx;
BN_MONT_CTX *in_mont;
{
int i,j,k,ret=0,tos,top;
int mul,sqr,num;
BIGNUM *d,*aa,*r,*a,*t;
BN_ULONG *vall[BN_EXP_TABLE_SIZE],*dp,*rp,n0,*rr,*tmp,*np;
BN_MONT_CTX *mont=NULL;
unsigned char *str=NULL;
#ifdef BN_SURRENDER
R_SURRENDER *surrender=NULL;
int count=0;
#endif
bn_check_top(a_in);
bn_check_top(p);
bn_check_top(m);
if (!(m->d[0] & 1))
{
#ifndef NO_ERR
BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);
#endif
return(0);
}
tos=ctx->tos;
if (BN_is_zero(a_in))
{ (void)BN_zero(rr_in); return(1); }
if (BN_is_zero(p))
{ (void)BN_one(rr_in); return(1); }
if (BN_is_one(p))
{ (void)BN_copy(rr_in,a_in); return(1); }
/* If this is not done, things will break in the montgomery
* part */
#if 1
if (in_mont != NULL)
mont=in_mont;
else
#endif
{
if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
}
#ifdef BN_SURRENDER
surrender=ctx->surrender;
#endif
if (!BN_gen_exp_bits(p,&str,0,ctx)) goto err;
/* Remember this function uses another element from the passed ctx */
ctx->tos++;
num=str[3];
i=(BN_BITS+str[2]-1)/str[2];
str+=4;
top=mont->N.top;
if ((a_in->top == top) && (a_in->d[top-1] < m->d[top-1]))
{
a=a_in;
}
else if (a_in->top < top)
{
a= &(ctx->bn[ctx->tos++]);
a->top=a_in->top;
bn_zexpand(a,top);
for (j=0; j<a_in->top; j++)
a->d[j]=a_in->d[j];
}
else /* if (a_in->top > i) */
{
a= &(ctx->bn[ctx->tos++]);
if (!BN_mod(a,a_in,m,ctx)) goto err;
bn_zexpand(a,top);
}
/* At this point a is the size of the modulus and is 0 padded
* out to its size if needed.
*/
/* Number of tmp words */
k=num*top;
j=k+(p->top*i*2+BN_BYTES-1+4)/BN_BYTES;
aa=&(ctx->bn[ctx->tos++]);
d= &(ctx->bn[ctx->tos++]);
r= &(ctx->bn[ctx->tos++]);
t= &(ctx->bn[ctx->tos++]);
if (bn_wexpand(rr_in,top) == NULL) goto err;
if (bn_wexpand(d,top*4) == NULL) goto err; /* *2? */
if (bn_wexpand(r,top*2) == NULL) goto err;
if (bn_wexpand(aa,j) == NULL) goto err;
if (bn_wexpand(t,top*2) == NULL) goto err;
dp=d->d;
rp=r->d;
tmp=t->d;
rr=mont->RR.d;
n0=mont->n0;
np=mont->N.d;
vall[0]=aa->d;
bn_mul_normal(tmp,a->d,top,rr,top);
bn_from_montgomery_words(vall[0],tmp,np,top,n0);
if (num > 1)
{
bn_sqr_normal(tmp,vall[0],top,dp);
bn_from_montgomery_words(dp,tmp,np,top,n0);
for (i=1; i<num; i++)
{
vall[i]= &(vall[i-1][top]);
bn_mul_normal(tmp,vall[i-1],top,dp,top);
bn_from_montgomery_words(vall[i],tmp,np,top,n0);
}
}
mul= *(str++);
sqr= *(str++);
/* add all of the 255s together plus next less than 255
* 255 is a special case and should be treated as 256
* which is too big to fit in an unsigned char
*/
if(sqr == 255 && mul == 0)
{
mul = *(str++); /* grab next mul in case it is last */
while(*str == 255 && mul == 0)
{
sqr += 256;
str++;
mul = *(str++); /* increment the str pointer */
}
sqr+= *(str++) + 1; /* add last sqr value < 255 + 1 for 1st 255 */
}
/* Get the first element */
(void)Memcpy(rp,vall[mul>>1],sizeof(BN_ULONG)*top);
while (sqr != 0)
{
#ifdef BN_SURRENDER
/*
* Check this at the start of the loop rather than the
* end so we avoid as many of the bn operations as possible
*/
if (surrender != NULL)
{
if (surrender->callback(surrender,0xff, count++) != 0)
{
goto err;
}
}
#endif /* BN_SURRENDER */
/*
* check the abort flag at the start of the loop so we avoid
* as many of the bn operations as possible
*/
if (BN_CTX_get_flags(ctx, BN_CTX_FLG_ABORT))
{
goto err;
}
for (i=0; i<sqr; i++)
{
bn_sqr_normal(tmp,rp,top,dp);
bn_from_montgomery_words(rp,tmp,np,top,n0);
}
mul= *(str++);
sqr= *(str++);
/* add all of the 255s together plus next less than 255 */
if(sqr == 255 && mul == 0)
{
mul = *(str++); /* grab next mul */
while(str[0] == 255 && mul == 0)
{
sqr += 256;
str++;
mul = *(str++); /* increment the str pointer */
}
sqr+= *(str++) + 1; /* add last sqr value < 255 + 1 */
}
if ((mul == 0) && (sqr == 0)) break;
if ((sqr != 0) || (mul != 1))
{
bn_mul_normal(tmp,rp,top,vall[mul>>1],top);
bn_from_montgomery_words(rp,tmp,np,top,n0);
}
else
{
bn_mul_normal(tmp,rp,top,a->d,top);
bn_from_montgomery_words(rr_in->d,tmp,np,top,n0);
goto end;
}
}
/* if (mul != 1) */
{
for (i=top; i<top+top; i++)
rp[i]=0;
bn_from_montgomery_words(rr_in->d,rp,np,top,n0);
}
end: /* Use this to avoid an if */
/*
* Even if the operation has completed successfully, if the
* abort flag is set we want to abort so that anything
* calling this function will know not to continue.
*/
if (BN_CTX_get_flags(ctx, BN_CTX_FLG_ABORT))
{
goto err;
}
rr_in->top=top;
bn_fix_top(rr_in);
ret=1;
err:
#ifdef BN_SURRENDER
/*
* Even if the operation completed successfully we want to abort
* if the abort flag has been is set, so that subsequent operations
* do not continue. Allow the caller change to return value and
* cause the function to fail.
*/
if (surrender != NULL)
{
if (surrender->callback(surrender, 0xff, -1) != 0)
{
ret = 0;
}
}
#endif
if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
ctx->tos=tos;
return(ret);
}
/* #endif */

View File

@ -0,0 +1,267 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
/**
* @file bn_me.c
* @brief BN method functions and utilities
*/
#include "bn_lcl.h"
#include "bn_thx.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MOD_EXP_METH_DEFAULT
#define SPLIT_BN_MONT_CTX_USEIT
#define SPLIT_BN_ME_CTX_NAME
#define SPLIT_BN_ME_CTX_NEW
#define SPLIT_BN_ME_CTX_FREE
#define SPLIT_BN_ME_CTX_SET
#define SPLIT_BN_ME_CTX_MOD_EXP
#endif /* NO_SPLIT */
#ifndef NOPROTO
BN_ME_METH *bn_mod_exp_meth_default(int fallback);
#else
BN_ME_METH *bn_mod_exp_meth_default();
#endif
#ifdef SPLIT_BN_MOD_EXP_METH_DEFAULT
/**
* Returns the default mod_exp method, choose first available in the
* method table or a hardwired default
*
* @param fallback [In] Flag for choice of method
* - 0 use the first value in the method table
* - 1 use the all encompassing default method
*
* @pre BN_default_init() has been run setting up library
*
* @post
*
* @internal uses global table <i>bnme[]</i> and counter <i>me_num</i>
*
* @internal only read the BN_ME_METH_INFO table no need for locking
*
* @relates BN_library_init
* @relates BN_default_init
* @relates BN_ME_CTX_new
* @relates BN_ME_CTX_free
*
*/
BN_ME_METH *bn_mod_exp_meth_default(int fallback)
{
const BN_ME_METH *tmp;
#ifndef BN_LIBRARY_SMALL
BN_ME_METH_INFO *meth_info;
if(!fallback && ((meth_info = BN_bnme_get_info(0)) != NULL))
{
tmp = meth_info->meth();
}
else
#endif
{
/* set in bn.h or override bn_thx.h */
tmp = BN_ME_METH_DEFAULT();
}
return((BN_ME_METH *)tmp);
}
#endif
#ifdef SPLIT_BN_MONT_CTX_USEIT
#ifndef NOPROTO
int bn_mont_ctx_useit(int argi);
#else
int bn_mont_ctx_useit();
#endif
/**
* Montgomery method default useit function
*
* @param argi [In] reserved for future use
*
* @return 0 success
*/
int bn_mont_ctx_useit(int argi)
{
return(0);
}
#endif
#ifdef SPLIT_BN_ME_CTX_NAME
/**
* Retrieve the BN method name string
*
* @param ctx [In] Method
*
* @pre ctx is valid and not NULL
*
* @return string pointer
*/
char *BN_ME_CTX_name(BN_ME_CTX *ctx)
{
return(ctx->meth->name);
}
#endif
#ifdef SPLIT_BN_ME_CTX_NEW
/**
* Allocate a new BN_ME_CTX structure and assign method
*
* @param meth [In] Method to assign
* @param in [Out] Result BN_ME_CTX
*
* @note if meth is NULL system method default is used
*
* @retval pointer to BN_ME_CTX success
* @retval NULL failure
*/
BN_ME_CTX *BN_ME_CTX_new(BN_ME_METH *meth, BN_ME_CTX **in)
{
int i;
BN_ME_CTX *ret;
if (in == NULL)
in= &ret;
if (meth == NULL)
meth=bn_mod_exp_meth_default(0);
i=meth->init_ctx(meth,in);
if (i)
return(NULL);
else
return(*in);
}
#endif
#ifdef SPLIT_BN_ME_CTX_FREE
/**
* Free context method
*
* @param mctx [In] Context object to be deallocated
*
* @note it is the callers responsibility to set mctx to NULL after free
*
* @pre mctx is not NULL and is valide BN_ME_CTX
*/
void BN_ME_CTX_free(BN_ME_CTX *mctx)
{
mctx->meth->free_ctx(mctx);
}
#endif
#ifdef SPLIT_BN_ME_CTX_SET
/**
* Set value to BN_ME_CTX by identifier
*
* @param mctx [In] Method context object
* @param b [In] Big number
* @param cmd [In] Command identifier
* @param flags [In] Mask operation directives
* @param ctx [In] BN data store
*
* @note cmd values:
* @li BN_ME_SET_MOD will cause a method lookup is method not set
*
* @note passes control to set method in mctx
*
* @return result of mctx method set operation
*/
int BN_ME_CTX_set(BN_ME_CTX *mctx, BIGNUM *b, int cmd, int flags, BN_CTX *ctx)
{
#ifndef BN_LIBRARY_SMALL
#ifndef NOPROTO
const BN_ME_METH *(*meth)(void);
#else
const BN_ME_METH *(*meth)();
#endif
#endif /* BN_LIBRARY_SMALL */
/* If we are loading the modulus, and we do not have the
* no_lookup flag (without a null method)
*/
if ((cmd == BN_ME_SET_MOD) &&
((mctx->meth != NULL) && !(flags & BN_ME_SET_FLG_NO_LOOKUP)))
{
#ifndef BN_LIBRARY_SMALL
meth=(const BN_ME_METH*(*)(void))
BN_bnme_get(BN_num_bits(b),BN_BNME_F_BITS);
if (meth != NULL)
mctx->meth=meth();
else
#endif
mctx->meth=bn_mod_exp_meth_default(1);
}
return(mctx->meth->set(mctx,b,cmd,flags,ctx));
}
#endif
#ifdef SPLIT_BN_ME_CTX_MOD_EXP
/**
* Call method mod_exp operation
*
* @param mctx [In] Method context object
* @param ret [Out] Result
* @param a [In] Base value
* @param p [In] Exponent
* @param m [In] Modulus
* @param ctx [In] Data storage
*
* @pre <i>a</i> must be expandable
*
* @return 0 success
*/
int BN_ME_CTX_mod_exp(BN_ME_CTX *mctx, BIGNUM *ret, BIGNUM *a, BIGNUM *p,
BIGNUM *m, BN_CTX *ctx)
{
int wtop;
/* Before we call the method, make sure we are not doing 0^p,
* and p is not 0 or 1 */
if (BN_is_zero(a))
{ BN_zero(ret); return(0); }
if (p != NULL)
{
if (BN_is_zero(p))
{ BN_one(ret); return(0); }
else if (BN_is_one(p))
{ BN_copy(ret,a); return(0); }
}
/* wtop is the size 'a' needs to be for the method */
wtop=mctx->meth->num;
bn_zexpand(a,wtop);
return(mctx->meth->mod_exp(mctx,ret,a,p,ctx));
}
#endif
#endif

View File

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#undef BN_DEBUG
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MOD_MUL_MONTGOMERY
#define SPLIT_BN_FROM_MONTGOMERY
#define SPLIT_BN_MONT_CTX_NEW
#define SPLIT_BN_MONT_CTX_INIT
#define SPLIT_BN_MONT_CTX_FREE
#define SPLIT_BN_MONT_CTX_COPY
#endif /* NO_SPLIT */
/* #define DEBUG */
#ifdef SPLIT_BN_MOD_MUL_MONTGOMERY
/* We multiply a by b, generating a number 2n words long.
* This is then reduced by the montogmery number, which is
* n words. */
int BN_mod_mul_montgomery(r,a,b,mont,ctx)
BIGNUM *r,*a,*b;
BN_MONT_CTX *mont;
BN_CTX *ctx;
{
BIGNUM *tmp,*tmp2;
int ret=0,w;
int i;
bn_check_top(a);
bn_check_top(b);
w=mont->riw;
tmp= &(ctx->bn[ctx->tos++]);
tmp2= &(ctx->bn[ctx->tos++]);
bn_check_top(tmp);
bn_check_top(tmp2);
if (bn_wexpand(tmp,w+w) == NULL) goto err;
if (bn_wexpand(r,w+w) == NULL) goto err;
if (a == b)
{
if (bn_wexpand(tmp2,w+w) == NULL) goto err;
#ifdef BN_SQR_COMBA
if ((a->top == 8) && (a->top == b->top))
bn_sqr_comba8(tmp->d,a->d);
else
#endif
{
bn_sqr_normal(tmp->d,a->d,a->top,tmp2->d);
}
}
else
{
#ifdef BN_MUL_COMBA
if (a->top == 8)
bn_mul_comba8(tmp->d,a->d,b->d);
else
#endif
{
bn_mul_normal(tmp->d,a->d,a->top,b->d,b->top);
}
}
i=a->top+b->top;
while (i<(w+w))
{
tmp->d[i]=0;
i++;
}
tmp->top=w+w;
tmp->neg=0;
/* reduce from aRR to aR */
/* tmp->d is 2w words */
#if 0
bn_fix_top(tmp);
BN_from_montgomery_words(r,tmp,mont,ctx);
#else
bn_from_montgomery_words(r->d,tmp->d,mont->N.d,w,mont->n0);
#endif
r->top=w;
r->neg=0;
bn_fix_top(r);
ret=1;
err:
ctx->tos-=2;
return(ret);
}
#endif
#ifdef SPLIT_BN_FROM_MONTGOMERY
int BN_from_montgomery(ret,a,mont,ctx)
BIGNUM *ret;
BIGNUM *a;
BN_MONT_CTX *mont;
BN_CTX *ctx;
{
BIGNUM *n,*r;
BN_ULONG *np,*rp,n0,v0,v1,*nrp;
int al,nl,max,i;
int retn=0;
bn_check_top(a);
r= &(ctx->bn[ctx->tos]);
if (!BN_copy(r,a)) goto err1;
n= &(mont->N);
/* mont->riw is the size of mont->N in bits/words */
al=mont->riw;
nl=n->top;
if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
max=(nl+al+1); /* allow for overflow (no?) XXX */
if (bn_wexpand(r,max) == NULL) goto err1;
if (bn_wexpand(ret,max) == NULL) goto err1;
r->neg=a->neg^n->neg;
np=n->d;
rp=r->d;
nrp= &(r->d[nl]);
/* clear the top words of T */
for (i=r->top; i<max; i++) /* Memset? XXX */
r->d[i]=0;
r->top=max;
n0=mont->n0;
v1=0;
for (i=0; i<nl; i++)
{
v0=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
v0=(v1+v0)&BN_MASK2;
v1=(BN_ULONG)( (v0 < v1)?1:0 );
if ((nrp[0]=(nrp[0]+v0)&BN_MASK2) < v0)
v1++;
nrp++;
rp++;
}
nrp[0]=v1;
bn_fix_top(r);
/* mont->riw will be a multiple of the word size */
(void)BN_rshift(ret,r,mont->riw*BN_BITS2);
if (BN_ucmp(ret, &(mont->N)) >= 0)
{
(void)BN_usub(ret,ret,&(mont->N)); /* XXX */
}
retn=1;
err1:
return(retn);
}
#endif
#ifdef SPLIT_BN_MONT_CTX_NEW
BN_MONT_CTX *BN_MONT_CTX_new()
{
BN_MONT_CTX *ret;
if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL)
return(NULL);
BN_MONT_CTX_init(ret);
ret->flags=BN_FLG_MALLOCED;
return(ret);
}
#endif
#ifdef SPLIT_BN_MONT_CTX_INIT
void BN_MONT_CTX_init(ctx)
BN_MONT_CTX *ctx;
{
ctx->use_word=0;
ctx->riw=0;
BN_init(&(ctx->RR));
BN_init(&(ctx->N));
BN_init(&(ctx->Ni));
ctx->flags=0;
}
#endif
#ifdef SPLIT_BN_MONT_CTX_FREE
void BN_MONT_CTX_free(mont)
BN_MONT_CTX *mont;
{
BN_free(&(mont->RR));
BN_free(&(mont->N));
BN_free(&(mont->Ni));
if (mont->flags & BN_FLG_MALLOCED)
Free(mont);
}
#endif
#ifdef SPLIT_BN_MONT_CTX_COPY
BN_MONT_CTX *BN_MONT_CTX_copy(to, from)
BN_MONT_CTX *to, *from;
{
if (to == from) return(to);
(void)BN_copy(&(to->RR),&(from->RR));
(void)BN_copy(&(to->N),&(from->N));
(void)BN_copy(&(to->Ni),&(from->Ni));
bn_zexpand(&(to->RR),from->riw);
bn_zexpand(&(to->Ni),from->riw);
to->use_word=from->use_word;
to->riw=from->riw;
to->n0=from->n0;
return(to);
}
#endif
#endif

View File

@ -0,0 +1,137 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
int BN_MONT_CTX_set_word(mont,mod,ctx)
BN_MONT_CTX *mont;
BIGNUM *mod;
BN_CTX *ctx;
{
BIGNUM Ri,*R;
#if 1
BN_ULONG tmod,rr;
#else
BN_ULONG buf[2];
BIGNUM tmod;
#endif
bn_check_top(mod);
if (mod->top == 0) return(0);
R= &(mont->RR); /* grab RR as a temp */
if (BN_copy(&(mont->N),mod) == NULL) /* Set N */
return(0);
BN_init(&Ri);
mont->use_word=1;
/* EAY is this number of words to shift, or the number to shift to end up
* with a '1' in the next word?
* for 8 bit words, is 0x01ab == 1 or 2
*/
mont->riw=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2;
if (!BN_zero(R)) return(0);
/* We are now setting a number which is larger than our current
* one after we do the shift
*/
if (!BN_set_bit(R,BN_BITS2))
goto err;
#if 0
tmod.d=buf;
tmod.top=1;
tmod.max=mod->max;
tmod.neg=mod->neg;
buf[0]=mod->d[0]&BN_MASK2;
buf[1]=0;
if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL)
goto err;
#else
tmod=mod->d[0];
rr=BN_mod_inverse_word(tmod);
if (!BN_set_word(&Ri,rr))
goto err;
#endif
/* R*Ri */
if (!BN_lshift(&Ri,&Ri,BN_BITS2))
goto err;
if (!BN_is_zero(&Ri))
(void)BN_sub_word(&Ri,1);
else
{
/* This is not common..., 1 in BN_MASK2,
* It happens when buf[0] was == 1. So for 8 bit,
* this is 1/256, 16bit, 1 in 2^16 etc.
*/
if (!BN_set_word(&Ri,BN_MASK2))
goto err;
}
#if 0
BN_div(&Ri,NULL,&Ri,&tmod,ctx);
//BN_div_word(&Ri,tmod);
mont->n0=Ri.d[0];
#else
#if 0
{
BN_ULONG h,l;
h=l=0;
if (Ri.top >= 2) h=Ri.d[1];
if (Ri.top >= 1) l=Ri.d[0];
mont->n0=bn_div_words(h,l,tmod);
}
#endif
mont->n0=bn_div_words(
(Ri.top >= 2)?Ri.d[1]:0,
(Ri.top >= 1)?Ri.d[0]:0,
tmod);
#endif
/* mod->top=z; */
/* setup RR for conversions */
(void)BN_zero(&(mont->RR));
if (!BN_set_bit(&(mont->RR),mont->riw*2*BN_BITS2))
goto err;
(void)BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx);
bn_zexpand(&(mont->RR),mont->riw);
#if 0
bn_zexpand(&(mont->Ni),mont->riw); /*This is not used? */
#endif
err:
BN_free(&Ri);
return(1);
}

View File

@ -0,0 +1,795 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MUL_RECURSIVE
#define SPLIT_BN_MUL_PART_RECURSIVE
#define SPLIT_BN_MUL_LOW_RECURSIVE
#define SPLIT_BN_MUL_HIGH
#define SPLIT_BN_MUL
#define SPLIT_BN_MUL_NORMAL
#define SPLIT_BN_MUL_LOW_NORMAL
#endif /* NO_SPLIT */
#ifdef SMALL_CODE_SIZE
#undef BN_RECURSION_MUL
#endif
#ifdef BN_RECURSION_MUL
#if 0 /* Replaced by bn_mul_rec_words() */
/* r is 2*n2 words in size,
* a and b are both n2 words in size.
* n2 must be a power of 2.
* We multiply and return the result.
* t must be 2*n2 words in size
* We calulate
* a[0]*b[0]
* a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
* a[1]*b[1]
*/
#ifdef SPLIT_BN_MUL_RECURSIVE
void bn_mul_recursive(r,a,b,n2,t)
BN_ULONG *r,*a,*b;
int n2;
BN_ULONG *t;
{
int n=n2/2,c1,c2;
unsigned int neg,zero;
BN_ULONG ln,lo,*p;
#ifdef BN_COUNT
printf(" bn_mul_recursive %d * %d\n",n2,n2);
#endif
#ifdef BN_MUL_COMBA
/* if (n2 == 4)
{
bn_mul_comba4(r,a,b);
return;
}
else */ if (n2 == 8)
{
bn_mul_comba8(r,a,b);
return;
}
#endif
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
{
/* This should not happen */
bn_mul_normal(r,a,n2,b,n2);
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
c1=bn_cmp_words(a,&(a[n]),n);
c2=bn_cmp_words(&(b[n]),b,n);
zero=neg=0;
switch (c1*3+c2)
{
case -4:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
break;
case -3:
zero=1;
break;
case -2:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
neg=1;
break;
case -1:
case 0:
case 1:
zero=1;
break;
case 2:
bn_sub_words(t, a, &(a[n]),n); /* + */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
neg=1;
break;
case 3:
zero=1;
break;
case 4:
bn_sub_words(t, a, &(a[n]),n);
bn_sub_words(&(t[n]),&(b[n]),b, n);
break;
}
#ifdef BN_MUL_COMBA
if (n == 4)
{
if (!zero)
bn_mul_comba4(&(t[n2]),t,&(t[n]));
else
Memset(&(t[n2]),0,8*sizeof(BN_ULONG));
bn_mul_comba4(r,a,b);
bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
}
else if (n == 8)
{
if (!zero)
bn_mul_comba8(&(t[n2]),t,&(t[n]));
else
Memset(&(t[n2]),0,16*sizeof(BN_ULONG));
bn_mul_comba8(r,a,b);
bn_mul_comba8(&(r[n2]),&(a[n]),&(b[n]));
}
else
#endif
{
p= &(t[n2*2]);
if (!zero)
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
else
Memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
bn_mul_recursive(r,a,b,n,p);
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
}
/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1=(int)bn_add_words(t,r,&(r[n2]),n2);
if (neg) /* if t[32] is negative */
{
c1-=(int)bn_sub_words(&(t[n2]),t,&(t[n2]),n2);
}
else
{
/* Might have a carry */
c1+=(int)bn_add_words(&(t[n2]),&(t[n2]),t,n2);
}
/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
* c1 holds the carry bits
*/
c1+=(int)bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2);
if (c1)
{
p= &(r[n+n2]);
lo= *p;
ln=(lo+c1)&BN_MASK2;
*p=ln;
/* The overflow will stop before we over write
* words we should not overwrite */
if (ln < (BN_ULONG)c1)
{
do {
p++;
lo= *p;
ln=(lo+1)&BN_MASK2;
*p=ln;
} while (ln == 0);
}
}
}
#endif
#endif
#if 0
#ifdef SPLIT_BN_MUL_PART_RECURSIVE
/* n+tn is the word length
* t must be n*4 is size, as does r */
void bn_mul_part_recursive(r,a,b,tn,n,t)
BN_ULONG *r,*a,*b;
int tn,n;
BN_ULONG *t;
{
int i,j,n2=n*2;
int c1;
BN_ULONG ln,lo,*p;
#ifdef BN_COUNT
printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
#endif
if (n < 8)
{
i=tn+n;
bn_mul_normal(r,a,i,b,i);
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
bn_sub_words(t, a, &(a[n]),n); /* + */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
#ifdef BN_MUL_COMBA
/* if (n == 4)
{
bn_mul_comba4(&(t[n2]),t,&(t[n]));
bn_mul_comba4(r,a,b);
bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
Memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
}
else */ if (n == 8)
{
bn_mul_comba8(&(t[n2]),t,&(t[n]));
bn_mul_comba8(r,a,b);
bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
Memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
}
else
#endif
{
p= &(t[n2*2]);
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
bn_mul_recursive(r,a,b,n,p);
i=n/2;
/* If there is only a bottom half to the number,
* just do it */
j=tn-i;
if (j == 0)
{
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
Memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
}
else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
{
bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
j,i,p);
Memset(&(r[n2+tn*2]),0,
sizeof(BN_ULONG)*(n2-tn*2));
}
else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
{
Memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL)
{
bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
}
else
{
for (;;)
{
i/=2;
if (i < tn)
{
bn_mul_part_recursive(&(r[n2]),
&(a[n]),&(b[n]),
tn-i,i,p);
break;
}
else if (i == tn)
{
bn_mul_recursive(&(r[n2]),
&(a[n]),&(b[n]),
i,p);
break;
}
}
}
}
}
/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1=(int)bn_add_words(t,r,&(r[n2]),n2);
c1-=(int)bn_sub_words(&(t[n2]),t,&(t[n2]),n2);
/* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
* c1 holds the carry bits
*/
c1+=(int)bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2);
if (c1)
{
p= &(r[n+n2]);
lo= *p;
ln=(lo+c1)&BN_MASK2;
*p=ln;
/* The overflow will stop before we over write
* words we should not overwrite */
if (ln < (BN_ULONG)c1)
{
do {
p++;
lo= *p;
ln=(lo+1)&BN_MASK2;
*p=ln;
} while (ln == 0);
}
}
}
#endif
#endif
#if 0
#ifdef SPLIT_BN_MUL_LOW_RECURSIVE
/* a and b must be the same size, which is n2.
* r must be n2 words and t must be n2*2
*/
void bn_mul_low_recursive(r,a,b,n2,t)
BN_ULONG *r,*a,*b;
int n2;
BN_ULONG *t;
{
int n=n2/2;
#ifdef BN_COUNT
printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
#endif
bn_mul_recursive(r,a,b,n,&(t[0]));
if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
{
bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
bn_mul_low_recursive(&(t[0]),&(a[n]),&(b[0]),n,&(t[n2]));
bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
}
else
{
bn_mul_low_normal(&(t[0]),&(a[0]),&(b[n]),n);
bn_mul_low_normal(&(t[n]),&(a[n]),&(b[0]),n);
bn_add_words(&(r[n]),&(r[n]),&(t[0]),n);
bn_add_words(&(r[n]),&(r[n]),&(t[n]),n);
}
}
#endif
#endif
#ifdef SPLIT_BN_MUL_HIGH
#if 0
/* a and b must be the same size, which is n2.
* r must be n2 words and t must be n2*2
* l is the low words of the output.
* t must be n2*3
*/
void bn_mul_high(r,a,b,l,n2,t)
BN_ULONG *r,*a,*b,*l;
int n2;
BN_ULONG *t;
{
int i,n;
int c1,c2;
int neg,oneg,zero;
BN_ULONG ll,lc,*lp,*mp;
#ifdef BN_COUNT
printf(" bn_mul_high %d * %d\n",n2,n2);
#endif
n=n2/2;
/* Calculate (al-ah)*(bh-bl) */
neg=zero=0;
c1=bn_cmp_words(&(a[0]),&(a[n]),n);
c2=bn_cmp_words(&(b[n]),&(b[0]),n);
switch (c1*3+c2)
{
case -4:
bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
break;
case -3:
zero=1;
break;
case -2:
bn_sub_words(&(r[0]),&(a[n]),&(a[0]),n);
bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
neg=1;
break;
case -1:
case 0:
case 1:
zero=1;
break;
case 2:
bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
bn_sub_words(&(r[n]),&(b[0]),&(b[n]),n);
neg=1;
break;
case 3:
zero=1;
break;
case 4:
bn_sub_words(&(r[0]),&(a[0]),&(a[n]),n);
bn_sub_words(&(r[n]),&(b[n]),&(b[0]),n);
break;
}
oneg=neg;
/* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
/* r[10] = (a[1]*b[1]) */
#ifdef BN_MUL_COMBA
if (n == 8)
{
bn_mul_comba8(&(t[0]),&(r[0]),&(r[n]));
bn_mul_comba8(r,&(a[n]),&(b[n]));
}
else
#endif
{
#ifdef BN_MUL_RECURSION
bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
#else
bn_mul_normal(&(t[0]),&(r[0]),n,&(r[n]),n);
bn_mul_normal(r,&(a[n]),n,&(b[n]),n);
#endif
}
/* s0 == low(al*bl)
* s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
* We know s0 and s1 so the only unknown is high(al*bl)
* high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
* high(al*bl) == s1 - (r[0]+l[0]+t[0])
*/
if (l != NULL)
{
lp= &(t[n2+n]);
c1=(int)bn_add_words(lp,&(r[0]),&(l[0]),n);
}
else
{
c1=0;
lp= &(r[0]);
}
if (neg)
neg=(int)bn_sub_words(&(t[n2]),lp,&(t[0]),n);
else
{
bn_add_words(&(t[n2]),lp,&(t[0]),n);
neg=0;
}
if (l != NULL)
{
bn_sub_words(&(t[n2+n]),&(l[n]),&(t[n2]),n);
}
else
{
lp= &(t[n2+n]);
mp= &(t[n2]);
for (i=0; i<n; i++)
lp[i]=((~mp[i])+1)&BN_MASK2;
}
/* s[0] = low(al*bl)
* t[3] = high(al*bl)
* t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
* r[10] = (a[1]*b[1])
*/
/* R[10] = al*bl
* R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
* R[32] = ah*bh
*/
/* R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
* R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
* R[3]=r[1]+(carry/borrow)
*/
if (l != NULL)
{
lp= &(t[n2]);
c1= (int)bn_add_words(lp,&(t[n2+n]),&(l[0]),n);
}
else
{
lp= &(t[n2+n]);
c1=0;
}
c1+=(int)bn_add_words(&(t[n2]),lp, &(r[0]),n);
if (oneg)
c1-=(int)bn_sub_words(&(t[n2]),&(t[n2]),&(t[0]),n);
else
c1+=(int)bn_add_words(&(t[n2]),&(t[n2]),&(t[0]),n);
c2 =(int)bn_add_words(&(r[0]),&(r[0]),&(t[n2+n]),n);
c2+=(int)bn_add_words(&(r[0]),&(r[0]),&(r[n]),n);
if (oneg)
c2-=(int)bn_sub_words(&(r[0]),&(r[0]),&(t[n]),n);
else
c2+=(int)bn_add_words(&(r[0]),&(r[0]),&(t[n]),n);
if (c1 != 0) /* Add starting at r[0], could be +ve or -ve */
{
i=0;
if (c1 > 0)
{
lc=c1;
do {
ll=(r[i]+lc)&BN_MASK2;
r[i++]=ll;
lc=(lc > ll);
} while (lc);
}
else
{
lc= -c1;
do {
ll=r[i];
r[i++]=(ll-lc)&BN_MASK2;
lc=(lc > ll);
} while (lc);
}
}
if (c2 != 0) /* Add starting at r[1] */
{
i=n;
if (c2 > 0)
{
lc=c2;
do {
ll=(r[i]+lc)&BN_MASK2;
r[i++]=ll;
lc=(lc > ll);
} while (lc);
}
else
{
lc= -c2;
do {
ll=r[i];
r[i++]=(ll-lc)&BN_MASK2;
lc=(lc > ll);
} while (lc);
}
}
}
#endif
#endif
#endif
#ifdef SPLIT_BN_MUL
int BN_mul(r,a,b,ctx)
BIGNUM *r,*a,*b;
BN_CTX *ctx;
{
int top,al,bl,neg;
BIGNUM *rr;
#ifdef BN_RECURSION_MUL
BIGNUM *t;
int i,j,k,l;
#endif
#ifdef BN_COUNT
printf("BN_mul %d * %d\n",a->top,b->top);
#endif
bn_check_top(a);
bn_check_top(b);
bn_check_top(r);
al=a->top;
bl=b->top;
if ((al == 0) || (bl == 0))
{
(void)BN_zero(r);
return(1);
}
top=al+bl;
neg=a->neg^b->neg;
if ((r == a) || (r == b))
rr= &(ctx->bn[ctx->tos+1]);
else
rr=r;
if (bn_wexpand(rr,top) == NULL) return(0);
rr->top=top;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION_MUL)
if (al == bl)
{
# ifdef BN_MUL_COMBA
/* if (al == 4)
{
bn_mul_comba4(rr->d,a->d,b->d);
goto end;
}
else */ if (al == 8)
{
bn_mul_comba8(rr->d,a->d,b->d);
goto end;
}
else
# endif
#ifdef BN_RECURSION_MUL
if (al < BN_MULL_SIZE_NORMAL)
#endif
{
bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end;
}
# ifdef BN_RECURSION_MUL
goto symetric;
# endif
}
#endif
#ifdef BN_RECURSION_MUL
else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL))
{
bn_mul_normal(rr->d,a->d,al,b->d,bl);
goto end;
}
else
{
i=(al-bl);
if ((i == 1) && !BN_get_flags(b,BN_FLG_STATIC_DATA))
{
bn_wexpand(b,al);
b->d[bl]=0;
bl++;
goto symetric;
}
else if ((i == -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
{
bn_wexpand(a,bl);
a->d[al]=0;
al++;
goto symetric;
}
}
#endif
#ifdef BN_RECURSION_MUL
normal_mul:
#endif
bn_mul_normal(rr->d,a->d,al,b->d,bl);
#ifdef BN_RECURSION_MUL
if (0)
{
symetric:
/* symetric and > 4 */
/* 16 or larger */
l=BN_num_bits_word((BN_ULONG)al);
j=1<<(l-1);
k=j+j;
t= &(ctx->bn[ctx->tos]);
if (al == j) /* exact multiple */
{
BN_REC rec;
rec.depth=l-5;
rec.n=j;
rec.mul=bn_mul_comba8;
rec.sqr=bn_sqr_comba8;
if (bn_wexpand(t,k+k) == NULL)
return(0);
if (bn_wexpand(rr,k) == NULL)
return(0);
bn_mul_rec_words(rr->d,a->d,b->d,t->d,&rec);
}
else
goto normal_mul;
#if 0
{
bn_zexpand(a,k);
bn_zexpand(b,k);
bn_wexpand(t,k);
bn_wexpand(rr,k);
bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
}
#endif
}
#endif
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION_MUL)
end:
#endif
r->neg=neg;
bn_fix_top(rr);
if (r != rr) (void)BN_copy(r,rr);
return(1);
}
#endif
#ifdef SPLIT_BN_MUL_NORMAL
void bn_mul_normal(r,a,na,b,nb)
BN_ULONG *r,*a;
int na;
BN_ULONG *b;
int nb;
{
BN_ULONG *rr;
#ifdef BN_COUNT
printf(" bn_mul_normal %d * %d\n",na,nb);
#endif
/* asymetric and >= 4 */
#if 0
if ((na == nb) && (na == 8))
{
bn_mul_normal(r,a,na,b,nb);
return;
}
#endif
if (na < nb)
{
int itmp;
BN_ULONG *ltmp;
itmp=na; na=nb; nb=itmp;
ltmp=a; a=b; b=ltmp;
}
rr= &(r[na]);
rr[0]=bn_mul_words(r,a,na,b[0]);
for (;;)
{
if (--nb <= 0) return;
rr[1]=bn_mul_add_words(&(r[1]),a,na,b[1]);
if (--nb <= 0) return;
rr[2]=bn_mul_add_words(&(r[2]),a,na,b[2]);
if (--nb <= 0) return;
rr[3]=bn_mul_add_words(&(r[3]),a,na,b[3]);
if (--nb <= 0) return;
rr[4]=bn_mul_add_words(&(r[4]),a,na,b[4]);
rr+=4;
r+=4;
b+=4;
}
}
#endif
#ifdef SPLIT_BN_MUL_LOW_NORMAL
void bn_mul_low_normal(r,a,b,n)
BN_ULONG *r,*a,*b;
int n;
{
#ifdef BN_COUNT
printf(" bn_mul_low_normal %d * %d\n",n,n);
#endif
(void)bn_mul_words(r,a,n,b[0]);
for (;;)
{
if (--n <= 0) return;
(void)bn_mul_add_words(&(r[1]),a,n,b[1]);
if (--n <= 0) return;
(void)bn_mul_add_words(&(r[2]),a,n,b[2]);
if (--n <= 0) return;
(void)bn_mul_add_words(&(r[3]),a,n,b[3]);
if (--n <= 0) return;
(void)bn_mul_add_words(&(r[4]),a,n,b[4]);
r+=4;
b+=4;
}
}
#endif
#endif

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
/* #ifdef RECP_MUL_MOD */
int BN_mod_exp_recp(r,a,p,m,ctx)
BIGNUM *r;
BIGNUM *a;
BIGNUM *p;
BIGNUM *m;
BN_CTX *ctx;
{
int i,j,bits,ret=0,wstart,wend,window,wvalue;
int start=1,ts=0;
BIGNUM *aa;
BIGNUM val[BN_EXP_TABLE_SIZE];
BN_RECP_CTX recp;
bits=BN_num_bits(p);
if (BN_is_zero(a))
{ (void)BN_zero(r); return(1); }
if (BN_is_zero(p))
{ (void)BN_one(r); return(1); }
if (BN_is_one(p))
{ (void)BN_copy(r,a); return(1); }
BN_RECP_CTX_init(&recp);
if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
BN_init(&(val[0]));
ts=1;
aa= &(ctx->bn[ctx->tos++]);
if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
goto err; /* 2 */
if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
window=1;
else if (bits >= 256)
window=5; /* max size of window */
else if (bits >= 128)
window=4;
else
window=3;
j=1<<(window-1);
for (i=1; i<j; i++)
{
BN_init(&val[i]);
if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
goto err;
}
ts=i;
start=1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue=0; /* The 'value' of the window */
wstart=bits-1; /* The top bit of the window */
wend=0; /* The bottom bit of the window */
if (!BN_one(r)) goto err;
for (;;)
{
if (BN_is_bit_set(p,wstart) == 0)
{
if (!start)
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
if (wstart == 0) break;
wstart--;
continue;
}
/* We now have wstart on a 'set' bit, we now need to work out
* how bit a window to do. To do this we need to scan
* forward until the last set bit before the end of the
* window */
j=wstart;
wvalue=1;
wend=0;
for (i=1; i<window; i++)
{
if (wstart-i < 0) break;
if (BN_is_bit_set(p,wstart-i))
{
wvalue<<=(i-wend);
wvalue|=1;
wend=i;
}
}
/* wend is the size of the current window */
j=wend+1;
/* add the 'bytes above' */
if (!start)
for (i=0; i<j; i++)
{
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
goto err;
/* move the 'window' down further */
wstart-=wend+1;
wvalue=0;
start=0;
if (wstart < 0) break;
}
ret=1;
err:
ctx->tos--;
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
BN_RECP_CTX_free(&recp);
return(ret);
}
/* #endif */

View File

@ -0,0 +1,249 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_2s_COMP
#define SPLIT_BN_MUL_REC_WORDS
#define SPLIT_BN_SQR_REC_WORDS
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_2s_COMP
void bn_2s_comp(r,a,n)
BN_ULONG *r,*a;
int n;
{
BN_ULONG l;
int i;
for (i=0; i<n; i++)
{
l=a[i];
l= ~l+1;
r[i]=l;
if (l != 0) break;
}
#if 1
for (i++; i<n; i++)
{
r[i]= ~a[i];
}
#else
for (i+=4; i<n; i+=4)
{
r[i-3]= ~a[i-3];
r[i-2]= ~a[i-2];
r[i-1]= ~a[i-1];
r[i ]= ~a[i ];
}
for (i-=3; i<n; i++)
{
r[i]= ~a[i];
}
#endif
}
#endif
#ifdef SPLIT_BN_MUL_REC_WORDS
/* t needs to be 2*n words */
void bn_mul_rec_words(r,a,b,tt,rec)
BN_ULONG *r,*a,*b,*tt;
BN_REC *rec;
{
int n=rec->n;
int n2=n/2;
int neg=0;
BN_ULONG c1;
if (rec->depth == 0)
{
/* t needs to have space for 4*n words
* The multiply needs to be a n2*n2 -> n
*/
#ifndef NOPROTO
void (PRE_CCONV CCONV *rmul)(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
#else
void (PRE_CCONV CCONV *rmul)();
#endif
rmul=rec->mul;
#ifdef _EXTRA_ARG_
/* THIS IS WRONG - there is no extra int arg on the end */
rmul(&(r[0]),&(a[0]),&(b[0]),n2);
rmul(&(r[n]),&(a[n2]),&(b[n2]),n2);
#else
rmul(&(r[0]),&(a[0]),&(b[0]));
rmul(&(r[n]),&(a[n2]),&(b[n2]));
#endif
if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2))
{
bn_2s_comp(&(tt[n+ 0]),&(tt[n+ 0]),n2);
neg=1;
}
else
neg=0;
if (bn_sub_words(&(tt[n+n2]),&(b[n2]),&(b[0]),n2))
{
neg^=1;
bn_2s_comp(&(tt[n+n2]),&(tt[n+n2]),n2);
}
#ifdef _EXTRA_ARG_
rmul(&(tt[0]),&(tt[n+0]),&(tt[n+n2]),n2);
#else
rmul(&(tt[0]),&(tt[n+0]),&(tt[n+n2]));
#endif
}
else /* Leaf node */
{
/* t has 4*n words taken per call.
* Since n is half the size per call, we need
* 6*n words for our current level and all sub levels
* The multiply needs to be a n2*n2 -> n
*/
rec->depth--;
rec->n=n2;
bn_mul_rec_words(&(r[0]), &(a[0]), &(b[0]), &(tt[n+n]),rec);
bn_mul_rec_words(&(r[n]), &(a[n2]),&(b[n2]), &(tt[n+n]),rec);
neg=0;
if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2))
{
bn_2s_comp(&(tt[n+ 0]),&(tt[n+ 0]),n2);
neg=1;
}
else
neg=0;
if (bn_sub_words(&(tt[n+n2]),&(b[n2]),&(b[0]),n2))
{
neg^=1;
bn_2s_comp(&(tt[n+n2]),&(tt[n+n2]),n2);
}
bn_mul_rec_words(&(tt[0]),&(tt[n]),&(tt[n+n2]),&(tt[n+n]),rec);
rec->n=n;
rec->depth++;
}
c1=bn_add_words(&(tt[n]),&(r[0]),&(r[n]),n);
if (neg)
c1-=bn_sub_words(&(tt[0]),&(tt[n]),&(tt[0]),n);
else
c1+=bn_add_words(&(tt[0]),&(tt[n]),&(tt[0]),n);
tt[n]=c1;
c1=bn_add_words(&(r[n2]),&(r[n2]),&(tt[0]),n+1);
if (c1)
{
tt= &(r[n+n2+1]);
do {
} while (++(*(tt++)) == 0);
}
}
#endif
#ifdef SPLIT_BN_SQR_REC_WORDS
/* tt needs to be 3*n words */
void bn_sqr_rec_words(r,a,tt,rec)
BN_ULONG *r,*a,*tt;
BN_REC *rec;
{
int n=rec->n;
int n2=n/2;
BN_ULONG c1;
if (rec->depth == 0)
{
/* t needs to have space for 4*n words
* The multiply needs to be a n2*n2 -> n
*/
#ifndef NOPROTO
void (PRE_CCONV CCONV *rsqr)(BN_ULONG *r, BN_ULONG *a);
#else
void (PRE_CCONV CCONV *rsqr)();
#endif
rsqr=rec->sqr;
#ifdef _EXTRA_ARG_
/* THIS IS WRONG - there is no extra int arg on the end */
rsqr(&(r[0]), &(a[0]), n2);
rsqr(&(r[n]), &(a[n2]),n2);
#else
rsqr(&(r[0]), &(a[0]));
rsqr(&(r[n]), &(a[n2]));
#endif
if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2))
bn_2s_comp(&(tt[n+0]),&tt[n+0], n2);
#ifdef _EXTRA_ARG_
rsqr(&(tt[0]),&(tt[n]), n2);
#else
rsqr(&(tt[0]),&(tt[n]));
#endif
}
else /* Leaf node */
{
/* t has 4*n words taken per call.
* Since n is half the size per call, we need
* 6*n words for our current level and all sub levels
* The multiply needs to be a n2*n2 -> n
*/
rec->depth--;
rec->n=n2;
bn_sqr_rec_words(&(r[0]), &(a[0]), &(tt[n+n]),rec);
bn_sqr_rec_words(&(r[n]), &(a[n2]),&(tt[n+n]),rec);
if (bn_sub_words(&(tt[n+0]), &(a[0]),&(a[n2]),n2))
bn_2s_comp(&(tt[n+0]),&tt[n+0], n2);
bn_sqr_rec_words(&(tt[0]),&(tt[n]),&(tt[n+n]),rec);
rec->n=n;
rec->depth++;
}
c1=bn_add_words(&(tt[n]),&(r[0]),&(r[n]),n);
c1-=bn_sub_words(&(tt[0]),&(tt[n]),&(tt[0]),n);
tt[n]=c1;
c1=bn_add_words(&(r[n2]),&(r[n2]),&(tt[0]),n+1);
if (c1)
{
tt= &(r[n+n2+1]);
do {
} while (++(*(tt++)) == 0);
}
}
#endif
#endif /* !NO_SPLIT || !SPLIT_FILE */

View File

@ -0,0 +1,218 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
void BN_RECP_CTX_init(recp)
BN_RECP_CTX *recp;
{
BN_init(&(recp->N));
BN_init(&(recp->Nr));
recp->num_bits=0;
recp->flags=0;
}
BN_RECP_CTX *BN_RECP_CTX_new()
{
BN_RECP_CTX *ret;
if ((ret=(BN_RECP_CTX *)Malloc(sizeof(BN_RECP_CTX))) == NULL)
return(NULL);
BN_RECP_CTX_init(ret);
ret->flags=BN_FLG_MALLOCED;
return(ret);
}
void BN_RECP_CTX_free(recp)
BN_RECP_CTX *recp;
{
BN_free(&(recp->N));
BN_free(&(recp->Nr));
if (recp->flags & BN_FLG_MALLOCED)
Free(recp);
}
int BN_RECP_CTX_set(recp,d,ctx)
BN_RECP_CTX *recp;
BIGNUM *d;
BN_CTX *ctx;
{
(void)BN_copy(&(recp->N),d);
(void)BN_zero(&(recp->Nr));
recp->num_bits=BN_num_bits(d);
recp->shift=0;
ctx=ctx; /* Stop warning */
return(1);
}
int BN_mod_mul_reciprocal(r, x, y, recp, ctx)
BIGNUM *r;
BIGNUM *x;
BIGNUM *y;
BN_RECP_CTX *recp;
BN_CTX *ctx;
{
int ret=0;
BIGNUM *a;
bn_check_top(x);
bn_check_top(y);
a= &(ctx->bn[ctx->tos++]);
if (y != NULL)
{
if (x == y)
{ if (!BN_sqr(a,x,ctx)) goto err; }
else
{ if (!BN_mul(a,x,y,ctx)) goto err; }
}
else
a=x; /* Just do the mod */
(void)BN_div_recp(NULL,r,a,recp,ctx);
ret=1;
err:
ctx->tos--;
return(ret);
}
int BN_div_recp(dv,rem,m,recp,ctx)
BIGNUM *dv;
BIGNUM *rem;
BIGNUM *m;
BN_RECP_CTX *recp;
BN_CTX *ctx;
{
int i,j,tos,ret=0,ex;
BIGNUM *a,*b,*d,*r;
bn_check_top(m);
tos=ctx->tos;
a= &(ctx->bn[ctx->tos++]);
b= &(ctx->bn[ctx->tos++]);
if (dv != NULL)
d=dv;
else
d= &(ctx->bn[ctx->tos++]);
if (rem != NULL)
r=rem;
else
r= &(ctx->bn[ctx->tos++]);
if (BN_ucmp(m,&(recp->N)) < 0)
{
(void)BN_zero(d);
(void)BN_copy(r,m);
ctx->tos=tos;
return(1);
}
/* We want the remainder
* Given input of ABCDEF / ab
* we need multiply ABCDEF by 3 digests of the reciprocal of ab
*
*/
i=BN_num_bits(m);
j=recp->num_bits*2;
if (j > i)
{
i=j;
ex=0;
}
else
{
ex=(i-j)/2;
}
j=i/2;
if (i != recp->shift)
recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),
i,ctx);
if (!BN_rshift(a,m,j-ex)) goto err;
if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;
if (!BN_rshift(d,b,j+ex)) goto err;
d->neg=0;
if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
if (!BN_usub(r,m,b)) goto err;
r->neg=0;
j=0;
#if 1
while (BN_ucmp(r,&(recp->N)) >= 0)
{
if (j++ > 2)
{
#ifndef NO_ERR
BNerr(BN_F_BN_DIV_RECP,BN_R_BAD_RECIPROCAL);
#endif
goto err;
}
if (!BN_usub(r,r,&(recp->N))) goto err;
if (!BN_add_word(d,1)) goto err;
}
#endif
r->neg=BN_is_zero(r)?0:m->neg;
d->neg=m->neg^recp->N.neg;
ret=1;
err:
ctx->tos=tos;
return(ret);
}
/* len is the expected size of the result
* We actually calculate with an extra word of precision, so
* we can do faster division if the remainder is not required.
*/
int BN_reciprocal(r,m,len,ctx)
BIGNUM *r;
BIGNUM *m;
int len;
BN_CTX *ctx;
{
int ret= -1;
BIGNUM t;
bn_check_top(m);
BN_init(&t);
(void)BN_zero(&t);
if (!BN_set_bit(&t,len)) goto err;
if (!BN_div(r,NULL,&t,m,ctx)) goto err;
ret=len;
err:
BN_free(&t);
return(ret);
}

View File

@ -0,0 +1,139 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_RSHIFT1
#define SPLIT_BN_RSHIFT
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_RSHIFT1
#ifdef SMALL_CODE_SIZE
int BN_rshift1(r, a)
BIGNUM *r;
BIGNUM *a;
{
return(BN_rshift(r,a,1));
}
#else
int BN_rshift1(r, a)
BIGNUM *r;
BIGNUM *a;
{
BN_ULONG *ap,*rp,t,c;
int i;
bn_check_top(a);
if (BN_is_zero(a))
{
BN_zero(r);
return(1);
}
if (a != r)
{
if (bn_wexpand(r,a->top) == NULL) return(0);
r->top=a->top;
r->neg=a->neg;
}
ap=a->d;
rp=r->d;
c=0;
for (i=a->top-1; i>=0; i--)
{
t=ap[i];
rp[i]=((t>>1)&BN_MASK2)|c;
c=(t&1)?BN_TBIT:0;
}
bn_fix_top(r);
return(1);
}
#endif
#endif
#ifdef SPLIT_BN_RSHIFT
int BN_rshift(r, a, n)
BIGNUM *r;
BIGNUM *a;
int n;
{
int i,j,nw,lb,rb;
BN_ULONG *t,*f;
BN_ULONG l,tmp;
bn_check_top(a);
#ifndef SMALL_CODE_SIZE
if (n == 1) return(BN_rshift1(r,a));
#endif
nw=n/BN_BITS2;
rb=n%BN_BITS2;
lb=BN_BITS2-rb;
if (nw > a->top)
{
(void)BN_zero(r);
return(1);
}
if (r != a)
{
if (bn_wexpand(r,a->top-nw+1+1/*???*/) == NULL) return(0);
r->neg=a->neg;
}
f= &(a->d[nw]);
t=r->d;
j=a->top-nw;
r->top=j;
if (rb == 0)
{
for (i=j+1; i > 0; i--)
*(t++)= *(f++);
}
else
{
l= *(f++);
for (i=1; i<j; i++)
{
tmp =(l>>rb)&BN_MASK2;
l= *(f++);
*(t++) =(tmp|(l<<lb))&BN_MASK2;
}
*(t++) =(l>>rb)&BN_MASK2;
*t=0;
}
bn_fix_top(r);
return(1);
}
#endif
#endif

View File

@ -0,0 +1,289 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#ifdef SMALL_CODE_SIZE
#undef BN_RECURSION_SQR
#endif
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_SQR
#define SPLIT_BN_SQR_NORMAL
#define SPLIT_BN_RECURSION_SQR
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_SQR
/* r must not be a */
int BN_sqr(r, a, ctx)
BIGNUM *r;
BIGNUM *a;
BN_CTX *ctx;
{
int max,al;
BIGNUM *tmp,*rr;
#ifdef BN_COUNT
printf("BN_sqr %d * %d\n",a->top,a->top);
#endif
bn_check_top(a);
tmp= &(ctx->bn[ctx->tos]);
rr=(a != r)?r: (&ctx->bn[ctx->tos+1]);
al=a->top;
if (al <= 0)
{
r->top=0;
return(1);
}
max=(al+al);
if (bn_wexpand(rr,max) == NULL) return(0);
rr->top=max;
rr->neg=0;
if (al == 4)
{
#ifndef BN_SQR_COMBA
BN_ULONG t[8];
bn_sqr_normal(rr->d,a->d,4,t);
#else
bn_sqr_comba4(rr->d,a->d);
#endif
}
else if (al == 8)
{
#ifndef BN_SQR_COMBA
BN_ULONG t[16];
bn_sqr_normal(rr->d,a->d,8,t);
#else
bn_sqr_comba8(rr->d,a->d);
#endif
}
else
{
#if 1 && defined(BN_RECURSION_SQR)
if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
{
BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
bn_sqr_normal(rr->d,a->d,al,t);
}
else
{
int j,l,k;
l=BN_num_bits_word((BN_ULONG)al);
j=1<<(l-1);
k=j+j;
if ((al == j) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
{
BN_REC rec;
if (bn_wexpand(tmp,k*2) == NULL) return(0);
rec.depth=l-5;
rec.n=j;
rec.mul=bn_mul_comba8;
rec.sqr=bn_sqr_comba8;
bn_sqr_rec_words(rr->d,a->d,tmp->d,&rec);
}
else
{
if (bn_wexpand(tmp,max) == NULL) return(0);
bn_assert(al*2 <= max);
bn_sqr_normal(rr->d,a->d,al,tmp->d);
}
}
#else
if (bn_wexpand(tmp,max) == NULL) return(0);
bn_assert(al*2 <= max);
bn_sqr_normal(rr->d,a->d,al,tmp->d);
#endif
#ifdef BN_DEBUG
tmp->top=0;
#endif
}
if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
if (rr != r) (void)BN_copy(r,rr);
return(1);
}
#endif
#ifdef SPLIT_BN_SQR_NORMAL
/* tmp must have 2*n words */
void bn_sqr_normal(r, a, n, tmp)
BN_ULONG *r;
BN_ULONG *a;
int n;
BN_ULONG *tmp;
{
int i,j,max;
BN_ULONG *ap,*rp,m;
max=n*2;
ap=a;
rp=r;
rp[0]=rp[max-1]=0;
rp++;
j=n;
if (--j > 0)
{
m= (*ap++);
rp[j]=bn_mul_words(rp,ap,j,m);
rp+=2;
}
for (i=n-2; i>0; i--)
{
j--;
m= *(ap++);
rp[j]=bn_mul_add_words(rp,ap,j,m);
rp+=2;
}
(void)bn_add_words(r,r,r,max);
/* There will not be a carry */
bn_sqr_words(tmp,a,n);
(void)bn_add_words(r,r,tmp,max);
}
#endif
#if 0 /* replaced by bn_sqr_rec_words() AND this has bugs */
#ifdef SPLIT_BN_RECURSION_SQR
#ifdef BN_RECURSION_SQR
/* r is 2*n words in size,
* a and b are both n words in size.
* n must be a power of 2.
* We multiply and return the result.
* t must be 2*n words in size
* We calulate
* a[0]*b[0]
* a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
* a[1]*b[1]
*/
void bn_sqr_recursive(r,a,n2,t)
BN_ULONG *r,*a;
int n2;
BN_ULONG *t;
{
int n=n2/2;
int zero,c1;
BN_ULONG ln,lo,*p;
#ifdef BN_COUNT
printf(" bn_sqr_recursive %d * %d\n",n2,n2);
#endif
if (n2 == 4)
{
#ifndef BN_SQR_COMBA
bn_sqr_normal(r,a,4,t);
#else
bn_sqr_comba4(r,a);
#endif
return;
}
else if (n2 == 8)
{
#ifndef BN_SQR_COMBA
bn_sqr_normal(r,a,8,t);
#else
bn_sqr_comba8(r,a);
#endif
return;
}
if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
{
bn_sqr_normal(r,a,n2,t);
return;
}
/* r=(a[0]-a[1])*(a[1]-a[0]) */
c1=bn_cmp_words(a,&(a[n]),n);
zero=0;
if (c1 > 0)
bn_sub_words(t,a,&(a[n]),n);
else if (c1 < 0)
bn_sub_words(t,&(a[n]),a,n);
else
zero=1;
/* The result will always be negative unless it is zero */
p= &(t[n2*2]);
if (!zero)
bn_sqr_recursive(&(t[n2]),t,n,p);
else
Memset(&(t[n2]),0,n*sizeof(BN_ULONG));
bn_sqr_recursive(r,a,n,p);
bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
/* t[32] is negative */
c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
* r[10] holds (a[0]*a[0])
* r[32] holds (a[1]*a[1])
* c1 holds the carry bits
*/
c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
if (c1)
{
p= &(r[n+n2]);
lo= *p;
ln=(lo+c1)&BN_MASK2;
*p=ln;
/* The overflow will stop before we over write
* words we should not overwrite */
if (ln < (BN_ULONG)c1)
{
do {
p++;
lo= *p;
ln=(lo+1)&BN_MASK2;
*p=ln;
} while (ln == 0);
}
}
}
#endif
#endif
#endif
#endif

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#ifndef OPT_BN_ASM
#ifndef BN_DIV_WORDS
#define BN_DIV_WORDS
#endif
#endif
#ifdef BN_DIV_WORDS
#if defined(BN_LLONG)
BN_ULONG bn_div_words(h,l,d)
BN_ULONG h,l,d;
{
return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d));
}
#else
/* Divide h-l by d and return the result. */
/* I need to test this some more */
BN_ULONG bn_div_words(h,l,d)
BN_ULONG h,l,d;
{
BN_ULONG dh,dl,q,ret=0,th,tl,t;
int i,count=2;
if (d == 0) return(BN_MASK2);
i=BN_num_bits_word(d);
if ((i != BN_BITS2) && (h > ((BN_ULONG)1)<<i))
{
return(0);
}
i=BN_BITS2-i;
if (h >= d) h-=d;
if (i)
{
d=(d<<i)&BN_MASK2;
h=((h<<i)|(l>>(BN_BITS2-i)))&BN_MASK2;
l=(l<<i)&BN_MASK2;
}
dh=(d>>BN_BITS4)&BN_MASK2lh;
dl=(d&BN_MASK2l);
for (;;)
{
if ((h>>BN_BITS4) == dh)
q=BN_MASK2l;
else
q=h/dh;
for (;;)
{
t=(h-q*dh)&BN_MASK2;
if ((t&BN_MASK2h) ||
(((dl*q)&BN_MASK2) <= ((
(t<<BN_BITS4)+
((l>>BN_BITS4)&BN_MASK2lh))&BN_MASK2)))
break;
q--;
}
th=(q*dh)&BN_MASK2;
tl=(q*dl)&BN_MASK2;
t=(tl>>BN_BITS4);
tl=(tl&BN_MASK2lh)<<BN_BITS4;
th=(th+t)&BN_MASK2;
if (l < tl) th++;
l=(l-tl)&BN_MASK2;
if (h < th)
{
h=(h+d)&BN_MASK2;
q--;
}
h=(h-th)&BN_MASK2;
if (--count == 0) break;
ret=(q&BN_MASK2lh)<<BN_BITS4;
h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2;
l=(l&BN_MASK2l)<<BN_BITS4;
}
ret|=q;
return(ret);
}
#endif
#endif /* BN_DIV_WORDS */

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_MOD_WORD
#define SPLIT_BN_DIV_WORD
#define SPLIT_BN_ADD_WORD
#define SPLIT_BN_SUB_WORD
#define SPLIT_BN_MUL_WORD
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_MOD_WORD
BN_ULONG BN_mod_word(a, w)
BIGNUM *a;
BN_ULONG w;
{
#ifndef BN_LLONG
BN_ULONG ret=0;
#else
BN_ULLONG ret=0;
#endif
int i;
w=w&BN_MASK2;//w&=BN_MASK2;
for (i=a->top-1; i>=0; i--)
{
#ifndef BN_LLONG
ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%w;
ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%w;
#else
ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])%
(BN_ULLONG)w);
#endif
}
return((BN_ULONG)ret);
}
#endif
#ifdef SPLIT_BN_DIV_WORD
BN_ULONG BN_div_word(a, w)
BIGNUM *a;
BN_ULONG w;
{
BN_ULONG ret;
int i;
if (a->top == 0) return(0);
ret=0;
w=w&BN_MASK2;//w&=BN_MASK2;
for (i=a->top-1; i>=0; i--)
{
BN_ULONG l,d;
l=a->d[i];
d=bn_div_words(ret,l,w);
ret=(l-((d*w)&BN_MASK2))&BN_MASK2;
a->d[i]=d;
}
if ((a->top > 0) && (a->d[a->top-1] == 0))
a->top--;
return(ret);
}
#endif
#ifdef SPLIT_BN_ADD_WORD
int BN_add_word(a, w)
BIGNUM *a;
BN_ULONG w;
{
BN_ULONG l;
int i;
if (w == 0) return(1);
bn_check_top(a);
w=w&BN_MASK2;//w&=BN_MASK2;
if (a->neg)
{
if(a->top > 1)
{
a->neg=0;
i=BN_sub_word(a,w);
a->neg=1;
return(i);
}
else
{ /* a->top == 1, it cannot be 0 */
l=a->d[0];
if (l > w)
a->d[0]=l-w;
else if (l < w)
{
a->neg=0;
a->d[0]=w-l;
}
else
{
a->neg=0;
a->top=0;
}
return(1);
}
}
w=w&BN_MASK2;//w&=BN_MASK2;
if (bn_wexpand(a,a->top+1) == NULL) return(0);
a->d[a->top]=0;
i=0;
for (;;)
{
l=(a->d[i]+(BN_ULONG)w)&BN_MASK2;
a->d[i]=l;
if (w > l)
w=1;
else
break;
i++;
}
if (i >= a->top)
a->top++;
return(1);
}
#endif
#ifdef SPLIT_BN_SUB_WORD
int BN_sub_word(a, w)
BIGNUM *a;
BN_ULONG w;
{
int i;
bn_check_top(a);
if (w == 0) return(1);
w=w&BN_MASK2;//w&=BN_MASK2;
if (a->neg)
{
a->neg=0;
i=BN_add_word(a,w);
a->neg=1;
return(i);
}
w=w&BN_MASK2;//w&=BN_MASK2;
if (a->top <= 1)
{
BN_ULONG l;
if (a->top == 0)
{
if (bn_wexpand(a,1) == NULL) return(0);
a->d[0]=w;
a->neg = 1;
a->top = 1;
return(1);
}
l=a->d[0];
if (l == w)
a->top=0;
else if (l > w)
a->d[0]=l-w;
else
{
a->neg=1;
a->d[0]=w-l;
}
return(1);
}
i=0;
for (;;)
{
if (a->d[i] >= w)
{
a->d[i]-=w;
break;
}
else
{
a->d[i]=(a->d[i]-w)&BN_MASK2;
i++;
w=1;
}
}
if ((a->d[i] == 0) && (i == (a->top-1)))
a->top--;
return(1);
}
#endif
#ifdef SPLIT_BN_MUL_WORD
int BN_mul_word(a,w)
BIGNUM *a;
BN_ULONG w;
{
BN_ULONG ll;
w=w&BN_MASK2;//w&=BN_MASK2;
if (a->top)
{
ll=bn_mul_words(a->d,a->d,a->top,w);
if (ll)
{
if (bn_wexpand(a,a->top+1) == NULL) return(0);
a->d[a->top++]=ll;
}
}
return(1);
}
#endif
#endif

View File

@ -0,0 +1,320 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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 <nitro.h>
#include <nitro/fs.h>
#include "acsign.h"
#include "acmemory.h"
/*---------------------------------------------------------------------------*/
unsigned long binarray[ 1024 * 1024 * 2 / sizeof (unsigned long) ];
unsigned long keyarray[ 1024 / sizeof (unsigned long) ];
unsigned long sgnarray[ 1024 / sizeof (unsigned long) ];
unsigned long bufferA[ ACSIGN_BUFFER / sizeof (unsigned long) ];
unsigned long bufferB[ ACSIGN_BUFFER / sizeof (unsigned long) ];
/*--------------------------------------------------------------------------*/
// ROMヘッダ
//----------------------------------------------------------------------
typedef struct {
//
// 0x000 System Reserved
//
char title_name[12]; // Soft title name
u32 game_code; // Game code
u16 maker_code; // Maker code
u8 machine_code; // Machine code
u8 rom_type; // Rom type
u8 rom_size; // Rom size
u8 reserved_A[9]; // System Reserved A ( Set ALL 0 )
u8 soft_version; // Soft version
u8 comp_arm9_boot_area:1; // Compress arm9 boot area
u8 comp_arm7_boot_area:1; // Compress arm7 boot area
u8 inspectCard:1; // 検査カードフラグ
u8 disableClearMemoryPad:1; // IPL2メモリパッドクリア・ディセーブルフラグ
u8 :0;
//
// 0x020 for Static modules (Section:B)
//
// ARM9
u32 main_rom_offset; // ROM offset
void* main_entry_address; // Entry point
void* main_ram_address; // RAM address
u32 main_size; // Module size
// ARM7
u32 sub_rom_offset; // ROM offset
void* sub_entry_address; // Entry point
void* sub_ram_address; // RAM address
u32 sub_size; // Module size
//
// 0x040 for File Name Table[FNT] (Section:C)
//
u32 fnt_offset; // ROM offset
u32 fnt_size; // Table size
//
// 0x048 for File Allocation Table[FAT] (Section:E)
//
u32 fat_offset; // ROM offset
u32 fat_size; // Table size
//
// 0x050 for Overlay Tables[OVT] (Section:D)
//
// ARM9
u32 main_ovt_offset; // ROM offset
u32 main_ovt_size; // Table size
// ARM7
u32 sub_ovt_offset; // ROM offset
u32 sub_ovt_size; // Table size
// 0x060 for ROM control parameter
u8 reserved_A2[32];
// 0x080 - 0x0C0 System Reserved
u8 reserved_B[64]; // System Reserved B (Set 0)
// 0x0C0 for NINTENDO logo data
u8 nintendo_logo[0x9c]; // NINTENDO logo data
u16 nintendo_logo_crc16; // CRC-16
// 0x15E ROM header CRC-16
u16 header_crc16; // ROM header CRC-16
} RomHeader;
/* V-blank callback */
static void VBlankIntr(void)
{
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
}
/*---------------------------------------------------------------------------*
Name: InitializeAllocateSystem
Description:
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
static void InitializeAllocateSystem(void)
{
void* tempLo;
OSHeapHandle hh;
// OS_Initは呼ばれているという前提
tempLo = OS_InitAlloc(
OS_ARENA_MAIN ,
OS_GetMainArenaLo() ,
OS_GetMainArenaHi() ,
1
);
OS_SetArenaLo(
OS_ARENA_MAIN ,
tempLo
);
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
);
}
//
static
void TestAC(char* iplfile, char* srlfile, char* sgnfile, FSFile* pfile )
{
RomHeader* pHeader;
const char* path;
BOOL fresult;
void* srl_ptr = 0;
long srl_len = 0;
void* key_ptr = 0;
long key_len = 0;
void* sgn_ptr = 0;
long sgn_len = 0;
if ( !pfile ) return ;
if ( !iplfile ) return ;
if ( !srlfile ) return ;
if ( !sgnfile ) return ;
path = iplfile;
if ( (fresult = FS_OpenFile(pfile, path)) )
{
key_len = FS_ReadFile( pfile, keyarray, sizeof keyarray );
key_ptr = keyarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
path = srlfile;
if ( (fresult = FS_OpenFile(pfile, path)) )
{
srl_len = FS_ReadFile( pfile, binarray, sizeof binarray );
srl_ptr = binarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
path = sgnfile; //"/data/sgn0.bin"; // sgn
if ( (fresult = FS_OpenFile(pfile, path)) )
{
sgn_len = FS_ReadFile( pfile, sgnarray, sizeof sgnarray );
sgn_ptr = sgnarray;
fresult = FS_CloseFile( pfile );
}
if ( !fresult )
OS_Printf("file read error! %s\n", path );
// 認証
if ( srl_ptr && srl_len && key_ptr && key_len && sgn_ptr && sgn_len )
{
long nSerial = 0;
pHeader = (RomHeader*)binarray;
MI_CpuFill8( bufferA, 0, sizeof bufferA );
MI_CpuFill8( bufferB, 0, sizeof bufferB );
#if 0
HMAC/Digtal Signature
>char seg_id[2]; //->"ac"に固定
>u16 version; //-> 1に固定
>u8 auth_code[20]/digital_sign[128]
>long serial_number
>char title_name[12]; // RomHeader.title_name
>u32 game_code; // RomHeader.game_code
>u16 maker_code; // RomHeader.make_code
>u8 machine_code; // RomHeader.machine_code
#endif
((unsigned char*)&nSerial)[0] = ((unsigned char*)sgn_ptr + 4 + 128)[0];
((unsigned char*)&nSerial)[1] = ((unsigned char*)sgn_ptr + 4 + 128)[1];
((unsigned char*)&nSerial)[2] = ((unsigned char*)sgn_ptr + 4 + 128)[2];
((unsigned char*)&nSerial)[3] = ((unsigned char*)sgn_ptr + 4 + 128)[3];
(void)ACSign_Decrypto( bufferA,
(char*)sgn_ptr + 4, // ファイル内の暗号化部分はへのオフセットをプラス
(char*)key_ptr + 16 ); // PC側でMODのみのファイルに対応すれば+16が不要
(void)ACSign_Digest( bufferB,
srl_ptr,
(char*)srl_ptr + pHeader->main_rom_offset,
pHeader->main_size,
(char*)srl_ptr + pHeader->sub_rom_offset,
pHeader->sub_size,
nSerial );
if ( ACSign_Compare( bufferA, bufferB ) )
{
OS_Printf( "Authentication_Code test : success! [%12s %12s] \n", srlfile, sgnfile );
}
else
{
OS_Printf( "Authentication_Code test : failure! [%12s %12s]\n", srlfile, sgnfile );
}
}
else
{
OS_Printf( "no test\n" );
}
OS_PrintServer();
}
void NitroMain(void)
{
FSFile file;
OS_InitPrintServer();
OS_Init();
OS_InitThread();
InitializeAllocateSystem();
OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)OS_EnableIrqMask(OS_IE_FIFO_RECV);
(void)OS_EnableIrq();
if ( sizeof (int ) < sizeof ( long ) )
OS_Printf( "sizeof (int ) != sizeof ( long )\n" );
if ( sizeof ( RomHeader ) != 0x0160 )
OS_Printf( "sizeof ( RomHeader ) != 0x0160\n" );
/* initialize file-system */
FS_Init( (u32)MI_DMA_MAX_NUM ); /* use DMA-3 for FS */
/* 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);
}
// ファイル読み込み
FS_InitFile(&file);
//TestAC( "/data/iplpub.bin", "/data/main.srl", "/data/sgn.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn0.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main1.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main2.srl", "/data/sgn2.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main3.srl", "/data/sgn3.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main4.srl", "/data/sgn4.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main5.srl", "/data/sgn5.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main6.srl", "/data/sgn6.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main7.srl", "/data/sgn7.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn7.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main3.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main5.srl", "/data/sgn5.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main1.srl", "/data/sgn0.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn1.bin", &file );
TestAC( "/data/iplpub.bin", "/data/main0.srl", "/data/sgn0.bin", &file );
OS_Terminate();
}

View File

@ -0,0 +1,412 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform(unsigned long [4], unsigned char [64]);
static void Encode(unsigned char *, unsigned long *, unsigned int);
static void Decode(unsigned long *, unsigned char *, unsigned int);
static void MD5_memcpy(unsigned char*, unsigned char*, unsigned int);
static void MD5_memset(unsigned char*, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (unsigned long)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init(context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update(context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((unsigned long)inputLen << 3)) < ((unsigned long)inputLen << 3))
context->count[1]++;
context->count[1] += ((unsigned long)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
MD5_memcpy((unsigned char*)&context->buffer[index], (unsigned char*)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy((unsigned char*)&context->buffer[index], (unsigned char*)&input[i], inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final(digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information. */
MD5_memset ((unsigned char*)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
unsigned long state[4];
unsigned char block[64];
{
unsigned long a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
MD5_memset ((unsigned char*)x, 0, sizeof (x));
}
/* Encodes input (unsigned long) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode(output, input, len)
unsigned char *output;
unsigned long *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j ] = (unsigned char)( input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (unsigned long). Assumes len is
a multiple of 4.
*/
static void Decode(output, input, len)
unsigned long *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((unsigned long)input[j]) | (((unsigned long)input[j+1]) << 8) |
(((unsigned long)input[j+2]) << 16) | (((unsigned long)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy(output, input, len)
unsigned char* output;
unsigned char* input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset(output, value, len)
unsigned char* output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
//////////////////////////////////////////////////////////////////////////////
#if defined( MD5_TEST )
#include <string.h>
char* samplearray[ 7 ] =
{
"",
"a",
"abc",
"message digest",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"1234567890" // x8
};
char* resultarray[ 7 ] =
{
"\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E",
"\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61",
"\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72",
"\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0",
"\xC3\xFC\xD3\xD7\x61\x92\xE4\x00\x7D\xFB\x49\x6C\xCA\x67\xE1\x3B",
"\xD1\x74\xAB\x98\xD2\x77\xD9\xF5\xA5\x61\x1C\x2C\x9F\x41\x9D\x9F",
"\x57\xED\xF4\xA2\x2B\xE3\xC9\x55\xAC\x49\xDA\x2E\x21\x07\xB6\x7A"
};
int repeatarray[ 7 ] =
{
1,
1,
1,
1,
1,
1,
8
};
int MD5Test( )
{
MD5_CTX context;
unsigned char digest[16];
int i, j, error;
error = 0;
for ( j = 0; j < 7; j++ )
{
MD5Init(&context);
for ( i = 0; i < repeatarray[j]; i++ )
{
MD5Update (&context,
(unsigned char*)samplearray[j],
(unsigned int)strlen( samplearray[j]) );
}
MD5Final(digest, &context);
error = memcmp( digest, resultarray[j], 16 );
if ( error )
break;
}
return error ? 0 : 1;
}
#endif // MD5_TEST
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,470 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* sha1.c
*
* Description:
* This file implements the Secure Hashing Algorithm 1 as
* defined in FIPS PUB 180-1 published April 17, 1995.
*
* The SHA-1, produces a 160-bit message digest for a given
* data stream. It should take about 2**n steps to find a
* message with the same digest as a given message and
* 2**(n/2) to find any two messages with the same digest,
* when n is the digest size in bits. Therefore, this
* algorithm can serve as a means of providing a
* "fingerprint" for a message.
*
* Portability Issues:
* SHA-1 is defined in terms of 32-bit "words". This code
* uses <stdint.h> (included via "sha1.h" to define 32 and 8
* bit unsigned integer types. If your C compiler does not
* support 32 bit unsigned integers, this code is not
* appropriate.
*
* Caveats:
* SHA-1 is designed to work with messages less than 2^64 bits
* long. Although SHA-1 allows a message digest to be generated
* for messages of any number of bits less than 2^64, this
* implementation only works with messages with a length that is
* a multiple of the size of an 8-bit character.
*
*/
#include "sha1.h"
/*
* Define the SHA1 circular left shift macro
*/
#define SHA1CircularShift(bits,word) \
(((word) << (bits)) | ((word) >> (32-(bits))))
/* Local Function Prototyptes */
void SHA1PadMessage(SHA1Context *);
void SHA1ProcessMessageBlock(SHA1Context *);
/*
* SHA1Reset
*
* Description:
* This function will initialize the SHA1Context in preparation
* for computing a new SHA1 message digest.
*
* Parameters:
* context: [in/out]
* The context to reset.
*
* Returns:
* sha Error Code.
*
*/
int SHA1Reset(SHA1Context *context)
{
if (!context)
{
return shaNull;
}
context->Length_Low = 0;
context->Length_High = 0;
context->Message_Block_Index = 0;
context->Intermediate_Hash[0] = 0x67452301;
context->Intermediate_Hash[1] = 0xEFCDAB89;
context->Intermediate_Hash[2] = 0x98BADCFE;
context->Intermediate_Hash[3] = 0x10325476;
context->Intermediate_Hash[4] = 0xC3D2E1F0;
context->Computed = 0;
context->Corrupted = 0;
return shaSuccess;
}
/*
* SHA1Result
*
* Description:
* This function will return the 160-bit message digest into the
* Message_Digest array provided by the caller.
* NOTE: The first octet of hash is stored in the 0th element,
* the last octet of hash in the 19th element.
*
* Parameters:
* context: [in/out]
* The context to use to calculate the SHA-1 hash.
* Message_Digest: [out]
* Where the digest is returned.
*
* Returns:
* sha Error Code.
*
*/
int SHA1Result( SHA1Context *context,
unsigned char Message_Digest[20])
{
int i;
if (!context || !Message_Digest)
{
return shaNull;
}
if (context->Corrupted)
{
return context->Corrupted;
}
if (!context->Computed)
{
SHA1PadMessage(context);
for(i=0; i<64; ++i)
{
/* message may be sensitive, clear it out */
context->Message_Block[i] = 0;
}
context->Length_Low = 0; /* and clear length */
context->Length_High = 0;
context->Computed = 1;
}
for(i = 0; i < 20; ++i)
{
Message_Digest[i] = (unsigned char)
(context->Intermediate_Hash[i>>2]
>> 8 * ( 3 - ( i & 0x03 ) ));
}
return shaSuccess;
}
/*
* SHA1Input
*
* Description:
* This function accepts an array of octets as the next portion
* of the message.
*
* Parameters:
* context: [in/out]
* The SHA context to update
* message_array: [in]
* An array of characters representing the next portion of
* the message.
* length: [in]
* The length of the message in message_array
*
* Returns:
* sha Error Code.
*
*/
int SHA1Input( SHA1Context *context,
const unsigned char *message_array,
unsigned int length)
{
if (!length)
{
return shaSuccess;
}
if (!context || !message_array)
{
return shaNull;
}
if (context->Computed)
{
context->Corrupted = shaStateError;
return shaStateError;
}
if (context->Corrupted)
{
return context->Corrupted;
}
while(length-- && !context->Corrupted)
{
context->Message_Block[context->Message_Block_Index++] =
(unsigned char)(*message_array & 0xFF);
context->Length_Low += 8;
if (context->Length_Low == 0)
{
context->Length_High++;
if (context->Length_High == 0)
{
/* Message is too long */
context->Corrupted = 1;
}
}
if (context->Message_Block_Index == 64)
{
SHA1ProcessMessageBlock(context);
}
message_array++;
}
return shaSuccess;
}
/*
* SHA1ProcessMessageBlock
*
* Description:
* This function will process the next 512 bits of the message
* stored in the Message_Block array.
*
* Parameters:
* None.
*
* Returns:
* Nothing.
*
* Comments:
*
* Many of the variable names in this code, especially the
* single character names, were used because those were the
* names used in the publication.
*
*
*/
void SHA1ProcessMessageBlock(SHA1Context *context)
{
const unsigned long K[] = { /* Constants defined in SHA-1 */
0x5A827999,
0x6ED9EBA1,
0x8F1BBCDC,
0xCA62C1D6
};
int t; /* Loop counter */
unsigned long temp; /* Temporary word value */
unsigned long W[80]; /* Word sequence */
unsigned long A, B, C, D, E; /* Word buffers */
/*
* Initialize the first 16 words in the array W
*/
for(t = 0; t < 16; t++)
{
W[t] = context->Message_Block[t * 4 ] << 24;
W[t] |= context->Message_Block[t * 4 + 1] << 16;
W[t] |= context->Message_Block[t * 4 + 2] << 8;
W[t] |= context->Message_Block[t * 4 + 3];
}
for(t = 16; t < 80; t++)
{
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
}
A = context->Intermediate_Hash[0];
B = context->Intermediate_Hash[1];
C = context->Intermediate_Hash[2];
D = context->Intermediate_Hash[3];
E = context->Intermediate_Hash[4];
for(t = 0; t < 20; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | ((~B) & D)) + E + W[t] + K[0];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 20; t < 40; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 40; t < 60; t++)
{
temp = SHA1CircularShift(5,A) +
((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
for(t = 60; t < 80; t++)
{
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
E = D;
D = C;
C = SHA1CircularShift(30,B);
B = A;
A = temp;
}
context->Intermediate_Hash[0] += A;
context->Intermediate_Hash[1] += B;
context->Intermediate_Hash[2] += C;
context->Intermediate_Hash[3] += D;
context->Intermediate_Hash[4] += E;
context->Message_Block_Index = 0;
}
/*
* SHA1PadMessage
*
* Description:
* According to the standard, the message must be padded to an even
* 512 bits. The first padding bit must be a '1'. The last 64
* bits represent the length of the original message. All bits in
* between should be 0. This function will pad the message
* according to those rules by filling the Message_Block array
* accordingly. It will also call the ProcessMessageBlock function
* provided appropriately. When it returns, it can be assumed that
* the message digest has been computed.
*
* Parameters:
* context: [in/out]
* The context to pad
* ProcessMessageBlock: [in]
* The appropriate SHA*ProcessMessageBlock function
* Returns:
* Nothing.
*
*/
void SHA1PadMessage(SHA1Context *context)
{
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second
* block.
*/
if (context->Message_Block_Index > 55)
{
context->Message_Block[context->Message_Block_Index++] = 0x80;
while(context->Message_Block_Index < 64)
{
context->Message_Block[context->Message_Block_Index++] = 0;
}
SHA1ProcessMessageBlock(context);
while(context->Message_Block_Index < 56)
{
context->Message_Block[context->Message_Block_Index++] = 0;
}
}
else
{
context->Message_Block[context->Message_Block_Index++] = 0x80;
while(context->Message_Block_Index < 56)
{
context->Message_Block[context->Message_Block_Index++] = 0;
}
}
/*
* Store the message length as the last 8 octets
*/
context->Message_Block[56] = (unsigned char)(context->Length_High >> 24);
context->Message_Block[57] = (unsigned char)(context->Length_High >> 16);
context->Message_Block[58] = (unsigned char)(context->Length_High >> 8);
context->Message_Block[59] = (unsigned char)(context->Length_High );
context->Message_Block[60] = (unsigned char)(context->Length_Low >> 24);
context->Message_Block[61] = (unsigned char)(context->Length_Low >> 16);
context->Message_Block[62] = (unsigned char)(context->Length_Low >> 8);
context->Message_Block[63] = (unsigned char)(context->Length_Low );
SHA1ProcessMessageBlock(context);
}
//////////////////////////////////////////////////////////////////////////////
#if defined( SHA1_TEST )
#include "string.h"
char* samplearray[4] =
{
"abc",
"abcdbcdecdefdefgefghfghighijhi" "jkijkljklmklmnlmnomnopnopq",
"a",
"01234567012345670123456701234567" "01234567012345670123456701234567"
};
char* resultarray[ 4 ] =
{
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D",
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1",
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F",
"\xDE\xA3\x56\xA2\xCD\xDD\x90\xC7\xA7\xEC\xED\xC5\xEB\xB5\x63\x93\x4F\x46\x04\x52"
};
long int repeatcount[4] = { 1, 1, 1000000, 10 };
int SHA1Test( )
{
SHA1Context sha;
unsigned char digest[20];
int i, j, error;
error = 0;
for ( j = 0; j < 4; ++j )
{
if ( !error )
error = SHA1Reset(&sha);
for(i = 0; i < repeatcount[j]; ++i)
{
if ( !error )
error = SHA1Input(&sha,
(const unsigned char *)samplearray[j],
(unsigned int)strlen(samplearray[j]));
}
if ( !error )
error = SHA1Result(&sha, digest);
if ( !error )
error = memcmp( digest, resultarray[j], 20 );
if (error)
break;
}
return error ? 0 : 1;
}
#endif // SHA1_TEST
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,786 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
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$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
////!!!!#include "r_com.h"
#ifndef NO_SHA1
#undef SHA_0
#define SHA_1
#include "sha.h"
#include "sha_locl.h"
#ifdef CPU_X86
#include "r_cpuid.h"
#endif /* NO_SHA1 */
const char *SHA1_version="SHA1 part of RCOM 2.3.0 11-Jun-2002";
/* Implemented from SHA-1 document - The Secure Hash Algorithm
*/
#define INIT_DATA_h0 (SHA_LONG)0x67452301L
#define INIT_DATA_h1 (SHA_LONG)0xefcdab89L
#define INIT_DATA_h2 (SHA_LONG)0x98badcfeL
#define INIT_DATA_h3 (SHA_LONG)0x10325476L
#define INIT_DATA_h4 (SHA_LONG)0xc3d2e1f0L
#define K_00_19 (SHA_LONG)0x5a827999L
#define K_20_39 (SHA_LONG)0x6ed9eba1L
#define K_40_59 (SHA_LONG)0x8f1bbcdcL
#define K_60_79 (SHA_LONG)0xca62c1d6L
#ifndef CCONV
#define CCONV
#endif
#ifndef PRE_CCONV
#define PRE_CCONV
#endif
/* Endian flags are only used for the assembler code */
#ifndef OPT_SHA1_ASM
#undef L_ENDIAN
#undef B_ENDIAN
#endif
#ifdef OPT_SHA1_ASM
#ifdef CPU_X86
void CCONV sha1_block_586(SHA_CTX *c,const unsigned char *p, int num);
void CCONV sha1_block_686(SHA_CTX *c,const unsigned char *p, int num);
void CCONV sha1_block_786(SHA_CTX *c,const unsigned char *p, int num);
unsigned long r_cpuid(unsigned long *,char **name);
#elif OPT_SHA1_ARM
PRE_CCONV void CCONV sha1_arm4_fast(SHA_CTX *c, const unsigned char *p,
int num);
PRE_CCONV void CCONV sha1_arm4_small(SHA_CTX *c, const unsigned char *p,
int num);
#else
void CCONV sha1_block_asm(SHA_CTX *c, const unsigned char *p, int num);
#endif /* CPU_X86 */
#else /* OPT_SHA1_ASM */
void sha1_block(SHA_CTX *c, SHA_LONG *p, int num);
#endif /* OPT_SHA1_ASM */
#undef M_c2nl
#undef M_p_c2nl
#undef M_c2nl_p
#undef M_p_c2nl_p
#undef M_nl2c
#if defined(L_ENDIAN) && !defined(OPT_SHA1_ASM)
# define M_c2nl c2l
# define M_p_c2nl p_c2l
# define M_c2nl_p c2l_p
# define M_p_c2nl_p p_c2l_p
# define M_nl2c l2c
#else
# define M_c2nl c2nl
# define M_p_c2nl p_c2nl
# define M_c2nl_p c2nl_p
# define M_p_c2nl_p p_c2nl_p
# define M_nl2c nl2c
#endif /* defined(L_ENDIAN) && !defined(OPT_SHA1_ASM) */
int SHA1_Setup(c,sha_block)
SHA_CTX *c;
void (PRE_CCONV CCONV *sha_block)(SHA_CTX *c, const unsigned char *W, int num);
{
c->sha_block=sha_block;
return(0);
}
void SHA1_Init(c)
SHA_CTX *c;
{
c->h0=INIT_DATA_h0;
c->h1=INIT_DATA_h1;
c->h2=INIT_DATA_h2;
c->h3=INIT_DATA_h3;
c->h4=INIT_DATA_h4;
c->Nl=0;
c->Nh=0;
c->num=0;
#ifdef OPT_SHA1_ASM
#ifdef CPU_X86
if (c->sha_block == NULL)
{
unsigned long cpu,attrib;
/* We should make the methods loadable */
cpu=r_cpuid(&attrib,NULL);
if (attrib & R_CPU_X86_HAS_PENTIUM_IV)
c->sha_block=sha1_block_786;
else if (attrib & R_CPU_X86_HAS_PENTIUM_PRO)
c->sha_block=sha1_block_686;
else
c->sha_block=sha1_block_586;
}
#else /* CPU_X86 */
#ifndef OPT_SHA1_ARM
c->sha_block=sha1_block_asm;
#else /* OPT_SHA1_ARM */
if (c->sha_block == NULL)
{
#ifdef SMALL_CODE_SIZE
c->sha_block = sha1_arm4_small;
#else /* SMALL_CODE_SIZE */
c->sha_block = sha1_arm4_fast;
#endif /* SMALL_CODE_SIZE */
}
#endif /* OPT_SHA1_ARM */
#endif /* CPU_X86 */
#else /* OPT_SHA1_ASM */
c->sha_block=(void (PRE_CCONV CCONV *)(SHA_CTX *, const unsigned char *, int))sha1_block;
#endif /* OPT_SHA1_ASM */
}
#ifdef OPT_SHA1_ASM
void SHA1_Update(c, data, len)
SHA_CTX *c;
const register unsigned char *data;
unsigned long len;
{
int i;
unsigned int alignment;
unsigned long l;
unsigned char *cp=(unsigned char *)c->data;
if (len == 0) return;
l=(c->Nl+(len<<3))&0xffffffffL;
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(len>>29);
c->Nl=l;
if (c->num != 0)
{
if (c->num+len >= SHA_CBLOCK)
{
i=SHA_CBLOCK-c->num;
Memcpy(&(cp[c->num]),data,i);
len-=i;
data+=i;
c->sha_block(c,cp,64);
c->num=0;
/* drop through and do the rest */
}
else
{
Memcpy(&(cp[c->num]),data,len);
c->num+=(int)len;
return;
}
}
/* we now can process the input data in blocks of SHA_CBLOCK
* chars and save the leftovers to c->data. */
if (len >= SHA_CBLOCK)
{
i=(int)(len& ~63);
len-=i;
/*
* Check to see if the input data lies on a word boundary.
* Do this as the ASM relies on input data being word aligned.
*/
alignment = (((unsigned int)data) & (sizeof(unsigned int)-1))
& 0x03;
if (alignment == 0)
{
c->sha_block(c,data,i);
data+=i;
}
else
{
do {
Memcpy(cp, data, SHA_CBLOCK);
data += SHA_CBLOCK;
c->sha_block(c, cp, SHA_CBLOCK);
i -= SHA_CBLOCK;
} while (i > 0);
}
}
c->num=len;
if (len)
{
Memcpy(cp,data,(int)len);
}
}
void SHA1_Transform(c,b)
SHA_CTX *c;
const unsigned char *b;
{
c->sha_block(c,b,64);
}
void SHA1_Final(md, c)
unsigned char *md;
SHA_CTX *c;
{
register int i,j;
register SHA_LONG l;
register SHA_LONG *p;
const static unsigned char end[4]={0x80,0x00,0x00,0x00};
unsigned char *cp= (unsigned char *)end;
unsigned char *pc;
/* c->num should definitly have room for at least one more byte. */
p=c->data;
j=c->num;
i=j>>2;
#ifdef PURIFY
/* PURIFY */
/* we reference uninitialised data but don't keep the result
* which purify complains about ... and we don't want to have
* to come back here to find a non-existant problem later
*/
/* purify often complains about the following line as an
* Uninitialized Memory Read. While this can be true, the
* following p_c2l macro will reset l when that case is true.
* This is because j&0x03 contains the number of 'valid' bytes
* already in p[i]. If and only if j&0x03 == 0, the UMR will
* occur but this is also the only time p_c2l will do
* l= *(cp++) instead of l|= *(cp++)
*/
if ((j&0x03) == 0) p[i]=0;
#endif
pc=(unsigned char *)c->data;
pc[j]=0x80;
for (j++; j & 0x03; j++)
pc[j]=0;
i++;
/* i is the next 'undefined word' */
if (c->num >= SHA_LAST_BLOCK)
{
for (; i<SHA_LBLOCK; i++)
p[i]=0;
c->sha_block(c,(unsigned char *)p,64);
i=0;
}
for (; i<(SHA_LBLOCK-2); i++)
p[i]=0;
l=c->Nl;
pc[63]=(unsigned char)((l )&0xff);
pc[62]=(unsigned char)((l>> 8)&0xff);
pc[61]=(unsigned char)((l>>16)&0xff);
pc[60]=(unsigned char)((l>>24)&0xff);
l=c->Nh;
pc[59]=(unsigned char)((l )&0xff);
pc[58]=(unsigned char)((l>> 8)&0xff);
pc[57]=(unsigned char)((l>>16)&0xff);
pc[56]=(unsigned char)((l>>24)&0xff);
c->sha_block(c,(unsigned char *)p,64);
cp=md;
l=c->h0; nl2c(l,cp);
l=c->h1; nl2c(l,cp);
l=c->h2; nl2c(l,cp);
l=c->h3; nl2c(l,cp);
l=c->h4; nl2c(l,cp);
/* clear stuff, sha1_block_asm may be leaving some stuff on the stack
* but I'm not worried :-) */
c->num=0;
/* Memset((char *)&c,0,sizeof(c));*/
}
#else /* !OPT_SHA1_ASM */
void SHA1_Update(c, data, len)
SHA_CTX *c;
const register unsigned char *data;
unsigned long len;
{
register SHA_LONG *p;
int ew,ec,sw,sc;
SHA_LONG l;
if (len == 0) return;
l=(c->Nl+(len<<3))&0xffffffffL;
if (l < c->Nl) /* overflow */
c->Nh++;
c->Nh+=(len>>29);
c->Nl=l;
if (c->num != 0)
{
p=c->data;
sw=c->num>>2;
sc=c->num&0x03;
if ((c->num+len) >= SHA_CBLOCK)
{
l= p[sw];
M_p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw<SHA_LBLOCK; sw++)
{
M_c2nl(data,l);
p[sw]=l;
}
len-=(SHA_CBLOCK-c->num);
c->sha_block(c,(unsigned char *)p,64);
c->num=0;
/* drop through and do the rest */
}
else
{
c->num+=(int)len;
if ((sc+len) < 4) /* ugly, add char's to a word */
{
l= p[sw];
M_p_c2nl_p(data,l,sc,len);
p[sw]=l;
}
else
{
ew=(c->num>>2);
ec=(c->num&0x03);
l= p[sw];
M_p_c2nl(data,l,sc);
p[sw++]=l;
for (; sw < ew; sw++)
{ M_c2nl(data,l); p[sw]=l; }
if (ec)
{
M_c2nl_p(data,l,ec);
p[sw]=l;
}
}
return;
}
}
/* We can only do the following code for assember, the reason
* being that the sha1_block 'C' version changes the values
* in the 'data' array. The assember code avoids this and
* copies it to a local array. I should be able to do this for
* the C version as well....
*/
#if defined(B_ENDIAN) || defined(OPT_SHA1_ASM)
if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0)
{
sw=len/SHA_CBLOCK;
if (sw)
{
sw*=SHA_CBLOCK;
c->sha_block(c,(SHA_LONG *)data,sw);
data+=sw;
len-=sw;
}
}
#endif
/* we now can process the input data in blocks of SHA_CBLOCK
* chars and save the leftovers to c->data. */
p=c->data;
while (len >= SHA_CBLOCK)
{
#if defined(B_ENDIAN) || defined(L_ENDIAN)
if (p != (SHA_LONG *)data)
Memcpy(p,data,SHA_CBLOCK);
data+=SHA_CBLOCK;
# ifdef L_ENDIAN
# ifndef OPT_SHA1_ASM /* Will not happen */
for (sw=(SHA_LBLOCK/4); sw; sw--)
{
Endian_Reverse32(p[0]);
Endian_Reverse32(p[1]);
Endian_Reverse32(p[2]);
Endian_Reverse32(p[3]);
p+=4;
}
p=c->data;
# endif
# endif
#else
for (sw=(SHA_BLOCK/4); sw; sw--)
{
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
M_c2nl(data,l); *(p++)=l;
}
p=c->data;
#endif
c->sha_block(c,(unsigned char *)p,64);
len-=SHA_CBLOCK;
}
ec=(int)len;
c->num=ec;
ew=(ec>>2);
ec&=0x03;
for (sw=0; sw < ew; sw++)
{ M_c2nl(data,l); p[sw]=l; }
M_c2nl_p(data,l,ec);
p[sw]=l;
}
void SHA1_Transform(c,b)
SHA_CTX *c;
const unsigned char *b;
{
SHA_LONG p[16];
#ifndef B_ENDIAN
SHA_LONG *q;
int i;
#endif
#if defined(B_ENDIAN) || defined(L_ENDIAN)
Memcpy(p,b,64);
#ifdef L_ENDIAN
q=p;
for (i=(SHA_LBLOCK/4); i; i--)
{
Endian_Reverse32(q[0]);
Endian_Reverse32(q[1]);
Endian_Reverse32(q[2]);
Endian_Reverse32(q[3]);
q+=4;
}
#endif
#else
q=p;
for (i=(SHA_LBLOCK/4); i; i--)
{
SHA_LONG l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
c2nl(b,l); *(q++)=l;
}
#endif
c->sha_block(c,(unsigned char *)p,64);
}
void sha1_block(c, W, num)
SHA_CTX *c;
SHA_LONG *W;
int num;
{
#ifndef SMALL_CODE_SIZE
register SHA_LONG A,B,C,D,E,T;
SHA_LONG X[16];
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
for (;;)
{
BODY_00_15( 0,A,B,C,D,E,T,W);
BODY_00_15( 1,T,A,B,C,D,E,W);
BODY_00_15( 2,E,T,A,B,C,D,W);
BODY_00_15( 3,D,E,T,A,B,C,W);
BODY_00_15( 4,C,D,E,T,A,B,W);
BODY_00_15( 5,B,C,D,E,T,A,W);
BODY_00_15( 6,A,B,C,D,E,T,W);
BODY_00_15( 7,T,A,B,C,D,E,W);
BODY_00_15( 8,E,T,A,B,C,D,W);
BODY_00_15( 9,D,E,T,A,B,C,W);
BODY_00_15(10,C,D,E,T,A,B,W);
BODY_00_15(11,B,C,D,E,T,A,W);
BODY_00_15(12,A,B,C,D,E,T,W);
BODY_00_15(13,T,A,B,C,D,E,W);
BODY_00_15(14,E,T,A,B,C,D,W);
BODY_00_15(15,D,E,T,A,B,C,W);
BODY_16_19(16,C,D,E,T,A,B,W,W,W,W);
BODY_16_19(17,B,C,D,E,T,A,W,W,W,W);
BODY_16_19(18,A,B,C,D,E,T,W,W,W,W);
BODY_16_19(19,T,A,B,C,D,E,W,W,W,X);
BODY_20_31(20,E,T,A,B,C,D,W,W,W,X);
BODY_20_31(21,D,E,T,A,B,C,W,W,W,X);
BODY_20_31(22,C,D,E,T,A,B,W,W,W,X);
BODY_20_31(23,B,C,D,E,T,A,W,W,W,X);
BODY_20_31(24,A,B,C,D,E,T,W,W,X,X);
BODY_20_31(25,T,A,B,C,D,E,W,W,X,X);
BODY_20_31(26,E,T,A,B,C,D,W,W,X,X);
BODY_20_31(27,D,E,T,A,B,C,W,W,X,X);
BODY_20_31(28,C,D,E,T,A,B,W,W,X,X);
BODY_20_31(29,B,C,D,E,T,A,W,W,X,X);
BODY_20_31(30,A,B,C,D,E,T,W,X,X,X);
BODY_20_31(31,T,A,B,C,D,E,W,X,X,X);
BODY_32_39(32,E,T,A,B,C,D,X);
BODY_32_39(33,D,E,T,A,B,C,X);
BODY_32_39(34,C,D,E,T,A,B,X);
BODY_32_39(35,B,C,D,E,T,A,X);
BODY_32_39(36,A,B,C,D,E,T,X);
BODY_32_39(37,T,A,B,C,D,E,X);
BODY_32_39(38,E,T,A,B,C,D,X);
BODY_32_39(39,D,E,T,A,B,C,X);
BODY_40_59(40,C,D,E,T,A,B,X);
BODY_40_59(41,B,C,D,E,T,A,X);
BODY_40_59(42,A,B,C,D,E,T,X);
BODY_40_59(43,T,A,B,C,D,E,X);
BODY_40_59(44,E,T,A,B,C,D,X);
BODY_40_59(45,D,E,T,A,B,C,X);
BODY_40_59(46,C,D,E,T,A,B,X);
BODY_40_59(47,B,C,D,E,T,A,X);
BODY_40_59(48,A,B,C,D,E,T,X);
BODY_40_59(49,T,A,B,C,D,E,X);
BODY_40_59(50,E,T,A,B,C,D,X);
BODY_40_59(51,D,E,T,A,B,C,X);
BODY_40_59(52,C,D,E,T,A,B,X);
BODY_40_59(53,B,C,D,E,T,A,X);
BODY_40_59(54,A,B,C,D,E,T,X);
BODY_40_59(55,T,A,B,C,D,E,X);
BODY_40_59(56,E,T,A,B,C,D,X);
BODY_40_59(57,D,E,T,A,B,C,X);
BODY_40_59(58,C,D,E,T,A,B,X);
BODY_40_59(59,B,C,D,E,T,A,X);
BODY_60_79(60,A,B,C,D,E,T,X);
BODY_60_79(61,T,A,B,C,D,E,X);
BODY_60_79(62,E,T,A,B,C,D,X);
BODY_60_79(63,D,E,T,A,B,C,X);
BODY_60_79(64,C,D,E,T,A,B,X);
BODY_60_79(65,B,C,D,E,T,A,X);
BODY_60_79(66,A,B,C,D,E,T,X);
BODY_60_79(67,T,A,B,C,D,E,X);
BODY_60_79(68,E,T,A,B,C,D,X);
BODY_60_79(69,D,E,T,A,B,C,X);
BODY_60_79(70,C,D,E,T,A,B,X);
BODY_60_79(71,B,C,D,E,T,A,X);
BODY_60_79(72,A,B,C,D,E,T,X);
BODY_60_79(73,T,A,B,C,D,E,X);
BODY_60_79(74,E,T,A,B,C,D,X);
BODY_60_79(75,D,E,T,A,B,C,X);
BODY_60_79(76,C,D,E,T,A,B,X);
BODY_60_79(77,B,C,D,E,T,A,X);
BODY_60_79(78,A,B,C,D,E,T,X);
BODY_60_79(79,T,A,B,C,D,E,X);
c->h0=(c->h0+E)&0xffffffffL;
c->h1=(c->h1+T)&0xffffffffL;
c->h2=(c->h2+A)&0xffffffffL;
c->h3=(c->h3+B)&0xffffffffL;
c->h4=(c->h4+C)&0xffffffffL;
num-=64;
if (num <= 0) break;
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
W+=16;
}
#else /* SMALL_CODE_SIZE */
SHA_LONG A,B,C,D,E,T;
SHA_LONG X[16];
SHA_LONG *a1,*a2,*a3;
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
for (;;)
{
int i;
for (i=0; i<16; i++)
{
BODY_00_15(i,A,B,C,D,E,T,W);
E=D; D=C; C=B; B=A; A=T;
}
a1=W;
for (i=16; i<20; i++)
{
if (i == 19) a1=X;
BODY_16_19(i,A,B,C,D,E,T,W,W,W,a1);
E=D; D=C; C=B; B=A; A=T;
}
a1=a2=a3=W;
for (i=20; i<40; i++)
{
if (i == 24) a3=X;
if (i == 30) a2=X;
if (i == 32) a1=X;
BODY_20_31(i,A,B,C,D,E,T,a1,a2,a3,X);
E=D; D=C; C=B; B=A; A=T;
}
for (i=40; i<60; i++)
{
BODY_40_59(i,A,B,C,D,E,T,X);
E=D; D=C; C=B; B=A; A=T;
}
for (i=60; i<80; i++)
{
BODY_60_79(i,A,B,C,D,E,T,X);
E=D; D=C; C=B; B=A; A=T;
}
c->h0=(c->h0+A)&0xffffffffL;
c->h1=(c->h1+B)&0xffffffffL;
c->h2=(c->h2+C)&0xffffffffL;
c->h3=(c->h3+D)&0xffffffffL;
c->h4=(c->h4+E)&0xffffffffL;
num-=64;
if (num <= 0) break;
A=c->h0;
B=c->h1;
C=c->h2;
D=c->h3;
E=c->h4;
W+=16;
}
#endif /* SMALL_CODE_SIZE */
}
void SHA1_Final(md, c)
unsigned char *md;
SHA_CTX *c;
{
register int i,j;
register SHA_LONG l;
register SHA_LONG *p;
const static unsigned char end[4]={0x80,0x00,0x00,0x00};
unsigned char *cp= (unsigned char *)end;
/* c->num should definitly have room for at least one more byte. */
p=c->data;
j=c->num;
i=j>>2;
#ifdef PURIFY
/* PURIFY */
/* we reference uninitialised data but don't keep the result
* which purify complains about ... and we don't want to have
* to come back here to find a non-existant problem later
*/
/* purify often complains about the following line as an
* Uninitialized Memory Read. While this can be true, the
* following p_c2l macro will reset l when that case is true.
* This is because j&0x03 contains the number of 'valid' bytes
* already in p[i]. If and only if j&0x03 == 0, the UMR will
* occur but this is also the only time p_c2l will do
* l= *(cp++) instead of l|= *(cp++)
*/
if ((j&0x03) == 0) p[i]=0;
#endif
l=p[i];
M_p_c2nl(cp,l,j&0x03);
p[i]=l;
i++;
/* i is the next 'undefined word' */
if (c->num >= SHA_LAST_BLOCK)
{
for (; i<SHA_LBLOCK; i++)
p[i]=0;
c->sha_block(c,(unsigned char *)p,64);
i=0;
}
for (; i<(SHA_LBLOCK-2); i++)
p[i]=0;
p[SHA_LBLOCK-2]=c->Nh;
p[SHA_LBLOCK-1]=c->Nl;
#if defined(L_ENDIAN)
Endian_Reverse32(p[SHA_LBLOCK-2]);
Endian_Reverse32(p[SHA_LBLOCK-1]);
#endif
c->sha_block(c,(unsigned char *)p,64);
cp=md;
l=c->h0; nl2c(l,cp);
l=c->h1; nl2c(l,cp);
l=c->h2; nl2c(l,cp);
l=c->h3; nl2c(l,cp);
l=c->h4; nl2c(l,cp);
/* clear stuff, sha1_block may be leaving some stuff on the stack
* but I'm not worried :-) */
c->num=0;
/* Memset((char *)&c,0,sizeof(c));*/
}
#endif
#if 0
int pr(ctx)
SHA_CTX *ctx;
{
int i,j;
unsigned char *p=(unsigned char *)(ctx->data);
fprintf(stderr,"num = %08X%08X\n",ctx->Nh,ctx->Nl);
fprintf(stderr," %08X %08X %08X %08X %08X\n",
ctx->h0,ctx->h1,ctx->h2,ctx->h3,ctx->h4);
fprintf(stderr,"bufnum = %d\n",ctx->num);
fprintf(stderr," ");
for (j=0; j<64; j+=16)
{
for (i=0; i<16; i++)
{
/*
if ((i+j) >= ctx->num)
fprintf(stderr,"--");
else
*/
fprintf(stderr,"%02X",p[i+j]);
}
if ((j+16) >=64)
fprintf(stderr,"\n");
else
fprintf(stderr,"\n ");
}
}
#endif
#endif /* NO_SHA1 */

View File

@ -0,0 +1,29 @@
#! 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:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS = ARM9
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,52 @@
#! 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:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM7
#----------------------------------------------------------------------------
SRCDIR = ../common/src
INCDIR = ../common/include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SRCS = mb_loader.c
TARGET_LIB = libmbloader_sp$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,51 @@
#! 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:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
#----------------------------------------------------------------------------
SRCDIR = ../common/src
INCDIR = ../common/include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include
SRCS = mb_loader.c
TARGET_LIB = libmbloader$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,29 @@
#! 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:: 2007-09-27#$
# $Rev: 1203 $
# $Author: yada $
#----------------------------------------------------------------------------
SUBDIRS = ARM7 ARM9
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,312 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: mb_loader.c
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.h>
#if defined(SDK_ARM7)
#include <nitro_wl/ARM7/WlLib.h>
#else
#ifdef SDK_SMALL_BUILD
#include "SYSM_work.h"
#endif
#endif
#include <nitro/mb.h> // twl/mb.hがない。
#include <mb_private.h>
#include <sysmenu/mb_loader.h>
// --------------------------------------------------------------------------
// Download情報のサイズ
#define MB_OVT_MAX_SIZE MB_COMM_BLOCK_SIZE // OVTの最大サイズBlockサイズを最大サイズとする
/*----------------------------------------------------------------------------*/
#define MB_TRIGGER_SIGNAL_TO_ARM7 (0x00000001)
/*----------------------------------------------------------------------------*/
static void MIm_CpuClear32( register u32 data, register void *destp, register u32 size );
static void MIm_CpuClear32( register u32 data, register void *destp, register u32 size );
static void LOADERi_LocateAllSegments( MBDownloadFileInfo *mdfi );
static void MBi_SearchAndLocateSegmentInfo( MBDownloadFileInfo *mdfi, u16 processor );
static void LOADERi_Jump(void);
static void MBi_fifo_callback_arm7(PXIFifoTag tag, u32 msg_adr, BOOL err);
/*----------------------------------------------------------------------------*/
static MB_LoaderCallback loader_precallback = NULL;
/*----------------------------------------------------------------------------*/
#if defined(SDK_ARM7)
/*---------------------------------------------------------------------------*
Name: MIm_CpuCopy32
Description: CpuCopy
Arguments: srcp, destp, size
Returns: void
*---------------------------------------------------------------------------*/
#include <nitro/code32.h>
asm void MIm_CpuCopy32( register const void *srcp, register void *destp, register u32 size )
{
add r12, r1, r2 // r12: destEndp = destp + size
@30:
cmp r1, r12 // while (destp < destEndp)
ldmltia r0!, {r2} // *((vu32 *)(destp)++) = *((vu32 *)(srcp)++)
stmltia r1!, {r2}
blt @30
bx lr
}
#ifndef SDK_SMALL_BUILD
static asm void MIm_CpuClear32( register u32 data, register void *destp, register u32 size )
{
add r12, r1, r2 // r12: destEndp = destp + size
@20:
cmp r1, r12 // while (destp < destEndp)
stmltia r1!, {r0} // *((vu32 *)(destp++)) = data
blt @20
bx lr
}
#endif
#include <nitro/codereset.h>
/*---------------------------------------------------------------------------*
Name: LOADERi_LocateAllSegments
Description: ARM9,ARM7の各セグメントを必要に応じて再配置する
Arguments: mdfi
Returns: void
*---------------------------------------------------------------------------*/
static void LOADERi_LocateAllSegments( MBDownloadFileInfo *mdfi )
{
MBi_SearchAndLocateSegmentInfo(mdfi, MI_PROCESSOR_ARM9); // ARM9セグメントについての配置処理
MBi_SearchAndLocateSegmentInfo(mdfi, MI_PROCESSOR_ARM7); // ARM7セグメントについての配置処理
}
/* 指定のセグメントを検索し, 再配置する */
static void MBi_SearchAndLocateSegmentInfo( MBDownloadFileInfo *mdfi, u16 processor )
{
int i;
MbSegmentInfo *seg_info;
if( mdfi ) {
for( i = 0 ; i < MB_DL_SEGMENT_NUM ; ++i ) {
seg_info = &mdfi->seg[i];
if ( seg_info->target == processor ) {
if ( seg_info->recv_addr != seg_info->load_addr ) {
MIm_CpuCopy32( (void*)seg_info->recv_addr, (void*)seg_info->load_addr, seg_info->size );
#ifndef SDK_SMALL_BUILD // ※IPL2の場合は、このメモリクリアはIPL2で行う。
MIm_CpuClear32( 0, (void*)seg_info->recv_addr, seg_info->size );
#endif
}
}
}
}
}
/*---------------------------------------------------------------------------*
Name: LOADERi_Jump
Description: (ARM7/9 )
Arguments:
Returns: void
*---------------------------------------------------------------------------*/
static void LOADERi_Jump(void)
{
#if defined(SDK_ARM7)
MBDownloadFileInfo *mdfi = (MBDownloadFileInfo*)MB_DOWNLOAD_FILEINFO_ADDRESS;
MBParam *p_param = (MBParam*)HW_WM_BOOT_BUF;
if( p_param->boot_type != MB_TYPE_MULTIBOOT ) { // ブートタイプがマルチブートでない場合は、何もせずにTRUEリターン。
return;
}
LOADERi_LocateAllSegments( mdfi ); // ブートプログラムの再配置を行う。
#endif
}
/*---------------------------------------------------------------------------*
Name: MBi_fifo_callback_arm7
Description: PXI
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
static void MBi_fifo_callback_arm7(PXIFifoTag tag, u32 msg_adr, BOOL err)
{
#pragma unused( err )
if (tag == PXI_FIFO_TAG_MB && msg_adr == (u32)MB_TRIGGER_SIGNAL_TO_ARM7)
{
if ( loader_precallback ) {
(*loader_precallback)();
}
}
}
#endif /* defined(SDK_ARM7) */
/*---------------------------------------------------------------------------*
Name: LOADER_Start
Description:
Arguments: None.
Returns: TRUE - success FALSE - failed
*---------------------------------------------------------------------------*/
void LOADER_Start(void)
{
#if defined(SDK_ARM9)
int result;
MBDownloadFileInfo *mdfi = (MBDownloadFileInfo*)MB_DOWNLOAD_FILEINFO_ADDRESS;
MBParam *p_param = (MBParam*)HW_WM_BOOT_BUF;
// マルチブートの時はデバッガエントリに飛ばないようクリアする。
#ifdef SDK_SMALL_BUILD
GetMovedInfoFromIPL1Addr()->isOnDebugger = 0; // USG-WW-3rd & USG-China-2ndでは、GetSharedWorkAddr()->isOnDebuggerはパッチ領域とモロバッティングしているが、このルーチンがARM9のマルチブートルーチンで呼ばれた後で、ARM7でパッチ挿入ルーチンが呼ばれるので、大丈夫。
// しかし、デバッガ版ビルド時には、参照する側のisOnDebuggerフラグがクリアされていなかったので、修正する。
#endif // SDK_SMALL_BUILD
// システム領域へマルチブートフラグを書き込み
p_param->boot_type = MB_TYPE_MULTIBOOT;
// 親機情報をシステム領域へ書き込み
MI_CpuCopy8((void*)MB_BSSDESC_ADDRESS, &p_param->parent_bss_desc, MB_BSSDESC_SIZE);
// ARM7側へローダー起動を通知
result = PXI_SendWordByFifo( PXI_FIFO_TAG_MB, (u32)MB_TRIGGER_SIGNAL_TO_ARM7, FALSE );
SDK_ASSERTMSG((result >= 0), "ARM9:FIFO SEND ERROR!\n");
return;
#else /* defined(SDK_ARM9) */
// ローダーをコール
LOADERi_Jump();
#endif
}
/*---------------------------------------------------------------------------*
Name: LOADER_Init
Description:
Arguments: callback -
Returns: None.
*---------------------------------------------------------------------------*/
void LOADER_Init(MB_LoaderCallback callback)
{
MBParam *p_param = (MBParam*)HW_WM_BOOT_BUF;
PXI_Init(); // 初期化されていなかったら、初期化処理を行う
#if defined(SDK_ARM7)
loader_precallback = callback;
/* ブートフラグの補正(マルチブートフラグが指定されていない場合はROMとみなす。) */
if (p_param->boot_type != MB_TYPE_MULTIBOOT) {
p_param->boot_type = MB_TYPE_NORMAL;
}
/* 上の処理で, 必ず MB_TYPE_MULTIBOOT か MB_TYPE_NORMAL になる */
// マルチブート監視FIFOコールバックをセット
PXI_SetFifoRecvCallback( PXI_FIFO_TAG_MB, MBi_fifo_callback_arm7 );
#else /* defined(SDK_ARM7) */
#pragma unused(callback)
#endif
}
/*----------------------------------------------------------------------------*
/* 現状 不使用
*----------------------------------------------------------------------------*/
#if defined(LOADER_USE_OVT_BUF)
//----------------------------------------------------------------------
// オーバーレイテーブル
//----------------------------------------------------------------------
typedef struct {
u32 id; // オーバーレイ ID
void *ram_address; // ロード先頭位置
u32 ram_size; // ロードサイズ
u32 bss_size; // bss 領域サイズ
void *sinit_init; // static initializer 先頭アドレス
void *sinit_init_end; // static initializer 最終アドレス
u32 file_id; // オーバーレイファイルID
u32 rsv; // 予約。
} ROM_OVT;
// OVTの最大サイズこれについては再考の余地あり
#define MB_OVT_MAX_SIZE MB_COMM_BLOCKSIZE
// Overlay Table Buffer
// マルチブートするプログラム上で、スタティックイニシャライザを起動するのに必要
// オーバーレイテーブル数で容量が変わってくる。
// IPL2における仕様が固まるまで、ここに置いておく
static u32 mb_ovt_buf[MB_OVT_MAX_SIZE/sizeof(u32)];
static void MB_SetOverlayTable(ROM_OVT *srcp, u16 sec_num)
{
if (srcp && sec_num)
{
MI_CpuCopy8((void*)srcp, (void*)mb_ovt_buf, sec_num*sizeof(ROM_OVT));
}
}
#endif

View File

@ -0,0 +1,46 @@
#! 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:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
SRCS = crt1.c
TARGET_OBJ = crt1.o
LINCLUDES = $(COMMON_DIR)
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,52 @@
#! 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:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
SUBDIRS =
MYSUBDIRS = ./
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TWL_PROC = ARM9
SRCS = sysmenu_lib.c sysmenu_card.c sysmenu_util.c gameBoot.c ninLogoFunc.c cmn.c \
nitroSettingsEx.c
TARGET_LIB = libsysmenu$(TWL_LIBSUFFIX).a
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(SYSMENU_INSTALL_LIBDIR)
LINCLUDES = $(TWLSDK_ROOT)/build/libraries/mb/common/include \
$(TWLSDK_ROOT)/build/libraries/spi/ARM9/include \
#----------------------------------------------------------------------------
do-build: $(MYSUBDIRS) $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
$(MYSUBDIRS)::
# $(MAKE) -C $@ -f MakeCrt0
#===== End of Makefile =====

View File

@ -0,0 +1,248 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_card.h
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$
*---------------------------------------------------------------------------*/
#ifndef SYSM_CARD_H_
#define SYSM_CARD_H_
#include <twl.h>
#ifdef __cplusplus
extern "C" {
#endif
//----------------------------------------------------------------------
// カード抜け検出
//
//・ARM7 がカードからのダウンロードを完了するまでは検出を開始しません。
//・検出処理中はカードバスへのアクセスをロックします。
//・アプリケーションを起動する前に SYSM_FinalizeCardPulledOut()
// を呼び出して確実に検出処理を完了させるようにして下さい。
//----------------------------------------------------------------------
BOOL SYSM_IsCardPulledOut(void);
//----------------------------------------------------------------------
// カード抜け検出終了処理
//----------------------------------------------------------------------
void SYSM_FinalizeCardPulledOut(void);
//----------------------------------------------------------------------
// カード抜け検出処理中か
//----------------------------------------------------------------------
BOOL SYSM_IsDetectingCardPulledOut(void);
//----------------------------------------------------------------------
// カード抜け検出初期化
//----------------------------------------------------------------------
void SYSMi_InitCardPulledOut(void);
//----------------------------------------------------------------------
// カードID読み込み
//----------------------------------------------------------------------
u32 SYSMi_ReadCardID(void);
//----------------------------------------------------------------------
// カードデータ読み込み
//----------------------------------------------------------------------
void SYSM_ReadCard(void *romp, void *ramp, s32 size);
//----------------------------------------------------------------------
// カードのデータ転送はレディか?
//----------------------------------------------------------------------
#define SYSMi_IsCardDataReady() \
\
(*(vu32 *)REG_CARDCNT & CARD_DATA_READY)
//・カードのデータ転送はレディかどうかを返します。
//----------------------------------------------------------------------
// カードデータ待ち
//----------------------------------------------------------------------
#define SYSMi_WaitCardData() \
{ \
while (!SYSMi_IsCardDataReady()) ; \
}
//・カードデータ転送の終了を待ちます。
//----------------------------------------------------------------------
// カードはビジーか?
//----------------------------------------------------------------------
#define SYSMi_IsCardBusy() \
\
(*(vu32 *)REG_CARDCNT & CARD_START)
//・カードがビジーかどうかを返します。
//----------------------------------------------------------------------
// カード待ち
//----------------------------------------------------------------------
#define SYSMi_WaitCard() \
{ \
while (SYSMi_IsCardBusy()) ; \
}
//・カードの終了を待ちます。
//----------------------------------------------------------------------
// コントロールパラメータ獲得GAMEモード
//----------------------------------------------------------------------
#define SYSMi_GetCardCnt4Game() \
\
(*(vu32 *)MROMCNT_GAME_BUF)
//・GAMEモードのコントロールパラメータを獲得します。
//----------------------------------------------------------------------
// ROMエリア・マップ
//----------------------------------------------------------------------
#define MROM_SECURE_AREA 0x4000 // SECUREエリア
#define MROM_GAME_AREA 0x8000 // GAMEエリア
//----------------------------------------------------------------------
// ROMエリア・サイズ
//----------------------------------------------------------------------
#define MROM_SEGMENT_SIZE 0x1000 // セグメントサイズ
#define MROM_SECURE_SIZE 0x4000 // SECUREエリアサイズ
#ifndef MROM_PAGE_SIZE
#define MROM_PAGE_SIZE 512 // マスクROM・ページ
#endif
//----------------------------------------------------------------------
// メモリ・マップ
//----------------------------------------------------------------------
#define MROMCNT_GAME_BUF (HW_ROM_HEADER_BUF + 0x60) // GAMEモード・コントロールデータ
#define MROMCNT_SECURE_BUF (HW_ROM_HEADER_BUF + 0x64) // SECUREモード・コントロールデータ
//----------------------------------------------------------------------
// レジスタ・アドレス
//----------------------------------------------------------------------
#ifndef REG_BASE
#define REG_BASE 0x04000000 // レジスタ群
#endif
#ifndef REG_IME
#define REG_IME (REG_BASE + 0x208) // 割り込みマスタイネーブル
#endif
#define REG_CARDMST_SPI_CNT (REG_BASE + 0x1a0) // カードマスター&SPIコントロール
#define REG_CARD_MASTER_CNT (REG_BASE + 0x1a1) // カードマスターコントロール
#define REG_CARD_SPI_CNT (REG_BASE + 0x1a0) // カードSPIコントロール
#define REG_CARD_SPI_DATA (REG_BASE + 0x1a2) // データ
#define REG_CARDCNT (REG_BASE + 0x1a4) // カードコントロール
#define REG_CARD_CMD (REG_BASE + 0x1a8) // コマンド設定
#define REG_CARD_DATA (REG_BASE + 0x100010) // データ
//----------------------------------------------------------------------
// カード マスターコントロール
//----------------------------------------------------------------------
#define CARDMST_SEL_DEVICE 0x20 // デバイス選択
#define CARDMST_SEL_ROM 0x00 // マスクROM/3Dメモリ選択
#define CARDMST_SEL_SPI 0x20 // SPI選択
#define CARDMST_IF_ENABLE 0x40 // 割り込み要求 許可
#define CARDMST_ENABLE 0x80 // カードイネーブル
//----------------------------------------------------------------------
// カードアクセス コントロール
//----------------------------------------------------------------------
#define CARD_LATENCY1_CYCLES_MASK 0x00001fff // レイテンシ1のサイクル数
#define CARD_LATENCY2_CYCLES_MASK 0x003f0000 // レイテンシ2のサイクル数
#define CARD_LATENCY_MASK 0x003f1fff // 上記を合わせたマスク
#define CARD_LATENCY1_CYCLES_SHIFT 0
#define CARD_LATENCY2_CYCLES_SHIFT 16
#define CARD_DATA_SCRAMBLE_ON 0x00002000 // データスクランブル
#define CARD_SCRAMBLE_UNIT_ON 0x00004000 // スクランブル回路
#define CARD_CMD_SCRAMBLE_ON 0x00400000 // コマンドスクランブル
// スクランブルフラグ群のセット
#define CARD_SCRAMBLE_SET_MASK ( CARD_SCRAMBLE_UNIT_ON | CARD_DATA_SCRAMBLE_ON \
| CARD_CMD_SCRAMBLE_ON)
#define CARD_DATA_READY 0x00800000 // データ レディ
#define CARD_1_PAGE 0x01000000 // 1ページ
#define CARD_STATUS 0x07000000 // ステータスリード
#define CARD_RESET_LO 0x00000000 // リセット信号レベル
#define CARD_RESET_HI 0x20000000 //
#define CARD_ACCESS_MODE 0x40000000 // アクセス モード
#define CARD_READ_MODE 0x00000000 // リードモード
#define CARD_WRITE_MODE 0x40000000 // ライトモード
#define CARD_START 0x80000000 // スタート
// 構造体メンバ用定数
#define ST_CARD_1_PAGE 1 // 1ページ
#define ST_CARD_STATUS 7 // ステータスリード
#define ST_CARD_READ_MODE 0 // リードモード
#define ST_CARD_WRITE_MODE 1 // ライトモード
//----------------------------------------------------------------------
// マスクROMコマンド
//----------------------------------------------------------------------
// GAMEモード
#define MROMOP_G_OP_MASK 0xff000000 // コマンドマスク
#define MROMOP_G_READ_ID 0xb8000000 // ID読み込み
#define MROMOP_G_READ_PAGE 0xb7000000 // ページ読み込み
#ifdef __cplusplus
} // extern "C"
#endif
#endif // SYSM_CARD_H_

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_define.h
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$
*---------------------------------------------------------------------------*/
#ifndef __SYSM_DEFINE_H__
#define __SYSM_DEFINE_H__
#include <twl.h>
#ifdef __cplusplus
extern "C" {
#endif
// define data-------------------------------------------
// 定数
#define POW_LCDC_SW_TOP 0x0000 // LCD上に画面表示
#define POW_LCDC_SW_BOTTOM 0x8000 // LCD下に画面表示
#define POW_E2D2 0x0200 // 2D回路2 の電源ON
#define POW_E2D1 0x0002 // 2D回路1 の電源ON
#define POW_ELC 0x0001 // LCDC回路の電源ON
#define SUBP_RECV_IF_ENABLE 0x4000 // 割り込み要求受信 許可
// 排他制御用ロックID
#define BOOTFLAG_LOCK_ID (OS_MAINP_LOCK_ID_END-1)
#define CARTRIDGE_LOCK_ID (OS_MAINP_LOCK_ID_END-2)
// SetBootFlag関数の引数int set_clear_flagで指定する定数
#define SBF_CLEAR 0
#define SBF_SET 1
#ifdef __cplusplus
}
#endif
#endif // __SYSM_DEFINE_H__

View File

@ -0,0 +1,250 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: mainFunc.c
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.h>
#include <nnsys.h>
#include <sysmenu/sysmenu_lib/ARM9/cmn.h>
/*---------------------------------------------------------------------------*
Name: CMN_InitFileSystem
Description:
Arguments: pAllocator:
Returns:
*---------------------------------------------------------------------------*/
// ファイルシステム準備
void CMN_InitFileSystem( NNSFndAllocator* pAllocator )
{
SDK_NULL_ASSERT( pAllocator );
// ARM7との通信FIFO割り込み許可
(void)OS_EnableIrqMask(OS_IE_SPFIFO_RECV);
// ファイルシステム初期化
FS_Init( FS_DMA_NOT_USE );
// ファイルテーブルキャッシュ
if( pAllocator != NULL )
{
const u32 need_size = FS_GetTableSize();
void *p_table = NNS_FndAllocFromAllocator( pAllocator, need_size );
SDK_ASSERT(p_table != NULL);
(void)FS_LoadTable(p_table, need_size);
}
}
/*---------------------------------------------------------------------------*
Name: CMN_ClearVram
Description: VRAM
VRAM
Arguments:
Returns:
*---------------------------------------------------------------------------*/
// VRAMクリア
void CMN_ClearVram( void )
{
//---------------------------------------------------------------------------
// All VRAM banks to LCDC
//---------------------------------------------------------------------------
GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
//---------------------------------------------------------------------------
// Clear all LCDC space
//---------------------------------------------------------------------------
MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
//---------------------------------------------------------------------------
// Disable the banks on LCDC
//---------------------------------------------------------------------------
(void)GX_DisableBankForLCDC();
MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // clear OAM
MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // clear the standard palette
MI_CpuFillFast((void*)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // clear OAM
MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // clear the standard palette
}
/*---------------------------------------------------------------------------*
Name: CMN_LoadFile
Description:
CMN_UnloadFile( *ppFile, pAlloc )
Arguments: ppFile:
fpath:
pAlloc:
Returns:
0
*ppFile
*---------------------------------------------------------------------------*/
u32 CMN_LoadFile(void** ppFile, const char* fpath, NNSFndAllocator* pAlloc)
{
BOOL bSuccess;
FSFile f;
u32 length;
u32 read;
SDK_NULL_ASSERT( ppFile );
SDK_NULL_ASSERT( fpath );
SDK_NULL_ASSERT( pAlloc );
FS_InitFile(&f);
bSuccess = FS_OpenFile(&f, fpath);
if( ! bSuccess )
{
OS_Warning("file (%s) not found", fpath);
return 0;
}
length = FS_GetLength(&f);
*ppFile = NNS_FndAllocFromAllocator(pAlloc, 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);
NNS_FndFreeToAllocator(pAlloc, *ppFile);
return 0;
}
bSuccess = FS_CloseFile(&f);
if( ! bSuccess )
{
OS_Warning("fail to close file: %s", fpath);
}
return length;
}
/*---------------------------------------------------------------------------*
Name: CMN_UnloadFile
Description:
Arguments: pFile:
pAlloc:
Returns:
*---------------------------------------------------------------------------*/
void CMN_UnloadFile(void* pFile, NNSFndAllocator* pAlloc)
{
NNS_FndFreeToAllocator(pAlloc, pFile);
}
/*---------------------------------------------------------------------------*
Name: CMN_LoadArchive
Description:
CMN_RemoveArchive( , pAllocator )
Arguments: name:
path:
pAllocator:
Returns: NNSFndArchive
NULLを返します
*---------------------------------------------------------------------------*/
NNSFndArchive*
CMN_LoadArchive(const char* name, const char* path, NNSFndAllocator* pAllocator)
{
FSFile file;
NNSFndArchive* archive = NULL;
SDK_NULL_ASSERT(name);
SDK_NULL_ASSERT(path);
SDK_NULL_ASSERT(pAllocator);
FS_InitFile(&file);
if (FS_OpenFile(&file, path))
{
u32 binarySize = FS_GetLength(&file);
u32 memorySize = MATH_ROUNDUP(sizeof(NNSFndArchive), 16) + MATH_ROUNDUP(binarySize, 16);
u8* memory = (u8*)NNS_FndAllocFromAllocator(pAllocator, memorySize);
if (memory != NULL)
{
u8* binary = memory + MATH_ROUNDUP(sizeof(NNSFndArchive), 16);
if ((u32)FS_ReadFile(&file, binary, (s32)binarySize) == binarySize)
{
if (NNS_FndMountArchive((NNSFndArchive*)memory, name, binary))
{
archive = (NNSFndArchive*)memory;
}
}
}
(void)FS_CloseFile(&file);
}
return archive;
}
/*---------------------------------------------------------------------------*
Name: CMN_RemoveArchive
Description:
Arguments: archive: NNSアーカイブ構造体へのポインタ
pAllocator:
Returns:
*---------------------------------------------------------------------------*/
void
CMN_RemoveArchive(NNSFndArchive* archive, NNSFndAllocator* pAllocator)
{
SDK_NULL_ASSERT(archive);
SDK_NULL_ASSERT(pAllocator);
(void)NNS_FndUnmountArchive(archive);
NNS_FndFreeToAllocator(pAllocator, archive);
}

View File

@ -0,0 +1,559 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: crt1.c
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/code32.h>
#include <twl.h>
#include <sysmenu/sysmenu_work.h> // SYSM changed.
#define SDK_NOCOMPRESS // SYSM changed.
extern void NitroMain( void );
extern void OS_IrqHandler( void );
static void do_autoload( void );
static void init_cp15( void );
void _start( void );
extern void* const _start_ModuleParams[];
void _start_AutoloadDoneCallback( void* argv[] );
extern void __call_static_initializers( void );
extern void _fp_init( void );
// from LCF
extern u32 SDK_IRQ_STACKSIZE[];
extern void SDK_AUTOLOAD_START( void ); // autoload data will start from here
extern void SDK_AUTOLOAD_LIST( void ); // start pointer to autoload information
extern void SDK_AUTOLOAD_LIST_END( void ); // end pointer to autoload information
extern void SDK_STATIC_BSS_START( void ); // static bss start address
extern void SDK_STATIC_BSS_END( void ); // static bss end address
/*---------------------------------------------------------------------------*
Name: _start
Description: Start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
#define INITi_HW_DTCM SDK_AUTOLOAD_DTCM_START
__declspec ( weak ) asm void _start( void )
{
//---- set IME = 0
// ( use that LSB of HW_REG_BASE equal to 0 )
mov r12, #HW_REG_BASE
str r12, [r12, #REG_IME_OFFSET]
//---- initialize cp15
bl init_cp15
//---- initialize stack pointer
// SVC mode
mov r0, #HW_PSR_SVC_MODE
msr cpsr_c, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
mov sp, r0
// IRQ mode
mov r0, #HW_PSR_IRQ_MODE
msr cpsr_c, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
sub r0, r0, #HW_SVC_STACK_SIZE
mov sp, r0
// System mode
ldr r1, =SDK_IRQ_STACKSIZE
sub r1, r0, r1
mov r0, #HW_PSR_SYS_MODE
msr cpsr_csfx, r0
sub sp, r1, #4 // 4byte for stack check code
//---- load autoload block and initialize bss
#ifndef SDK_NOCOMPRESS
ldr r1, =_start_ModuleParams
ldr r0, [r1, #20] // r0 = bottom of compressed data
bl MIi_UncompressBackward
#endif
bl do_autoload
//---- clear memory
// DTCM (16KB)
mov r0, #0
ldr r1, =INITi_HW_DTCM
mov r2, #HW_DTCM_SIZE
bl MIi_CpuClear32
/* // BG/OBJ palette (1KB) // SYSM changed.
mov r0, #0
ldr r1, =HW_PLTT
mov r2, #HW_PLTT_SIZE
bl MIi_CpuClear32
// OAM (1KB)
mov r0, #0x0200
ldr r1, =HW_OAM
mov r2, #HW_OAM_SIZE
bl MIi_CpuClear32
*/
//---- set interrupt vector
ldr r1, =INITi_HW_DTCM
add r1, r1, #0x3fc0
add r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR
ldr r0, =OS_IrqHandler
str r0, [r1, #0]
#ifndef SDK_NOINIT
//---- for C++
bl _fp_init
bl NitroStartUp
bl __call_static_initializers
#endif
//---- start (to 16bit code)
ldr r1, =NitroMain
// ldr lr, =HW_RESET_VECTOR
ldr lr, =RETURN_FROM_MAIN_ARM9_FUNCP // SYSM changed.
bx r1
}
/*---------------------------------------------------------------------------*
Name: _start_ModuleParams
Description: autoload/compress/arguments data block
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
void* const _start_ModuleParams[] =
{
(void*)SDK_AUTOLOAD_LIST,
(void*)SDK_AUTOLOAD_LIST_END,
(void*)SDK_AUTOLOAD_START,
(void*)SDK_STATIC_BSS_START,
(void*)SDK_STATIC_BSS_END,
#ifndef SDK_NOCOMPRESS
(void*)0, // CompressedStaticEnd
#endif
};
/*---------------------------------------------------------------------------*
Name: MIi_UncompressBackward
Description: Uncompress special archive for module compression
Arguments: bottom = Bottom adrs of packed archive + 1
bottom[-12] = offset for top of compressed data
inp_top = bottom + bottom[-12]
bottom[ -8] = offset for bottom of compressed data
inp = bottom + bottom[ -8]
bottom[ -4] = offset for bottom of original data
outp = bottom + bottom[ -4]
typedef struct
{
int bufferTop;
int compressBottom;
int originalBottom;
} CompFooter;
Returns: None.
*---------------------------------------------------------------------------*/
asm void MIi_UncompressBackward( register void* bottom )
{
#define data r0
#define inp_top r1
#define outp r2
#define inp r3
#define outp_save r4
#define flag r5
#define count8 r6
#define index r7
#define len r12
cmp bottom, #0
beq @exit
stmfd sp!, {r4-r7}
ldmdb bottom, {r1-r2}
add outp, bottom, outp
sub inp, bottom, inp_top, LSR #24
bic inp_top, inp_top, #0xff000000
sub inp_top, bottom, inp_top
mov outp_save, outp
@loop:
cmp inp, inp_top // exit if inp==inp_top
ble @end_loop
ldrb flag, [inp, #-1]! // r4 = compress_flag = *--inp
mov count8, #8
@loop8:
subs count8, count8, #1
blt @loop
tst flag, #0x80
bne @blockcopy
@bytecopy:
ldrb data, [inp, #-1]!
#ifdef SDK_TEG
sub outp, outp, #1
swpb data, data, [outp]
#else
strb data, [outp, #-1]! // Copy 1 byte
#endif
b @joinhere
@blockcopy:
ldrb len, [inp, #-1]!
ldrb index, [inp, #-1]!
orr index, index, len, LSL #8
bic index, index, #0xf000
add index, index, #0x0002
add len, len, #0x0020
@patterncopy:
ldrb data, [outp, index]
#ifdef SDK_TEG
sub outp, outp, #1
swpb data, data, [outp]
#else
strb data, [outp, #-1]!
#endif
subs len, len, #0x0010
bge @patterncopy
@joinhere:
cmp inp, inp_top
mov flag, flag, LSL #1
bgt @loop8
@end_loop:
// DC_FlushRange & IC_InvalidateRange
bic inp, inp_top, #HW_CACHE_LINE_SIZE - 1
@cacheflush:
mcr p15, 0, inp, c7, c5, 1 // ICache
mcr p15, 0, inp, c7, c14, 1 // DCache
add inp, inp, #HW_CACHE_LINE_SIZE
cmp inp, outp_save
blt @cacheflush
ldmfd sp!, {r4-r7}
@exit bx lr
}
/*---------------------------------------------------------------------------*
Name: do_autoload
Description: put autoload data block according to autoload information,
and clear static bss by filling with 0.
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
static asm void do_autoload( void )
{
#define ptable r0
#define infop r1
#define infop_end r2
#define src r3
#define dest r4
#define dest_size r5
#define dest_end r6
#define tmp r7
ldr ptable, =_start_ModuleParams
ldr infop, [ptable, #0] // r1 = start pointer to autoload_info
ldr infop_end, [ptable, #4] // r2 = end pointer to autoload_info
ldr src, [ptable, #8] // r3 = autoload block
@2:
cmp infop, infop_end // reach to end?
beq @fill_bss
ldr dest, [infop], #4 // dest
ldr dest_size, [infop], #4 // size
add dest_end, dest, dest_size // dest_end
@1:
cmp dest, dest_end
ldrmi tmp, [src], #4 // [dest++] <- [src++]
strmi tmp, [dest], #4
bmi @1
//---- fill bss with 0
ldr dest_size, [infop], #4 // size
add dest_end, dest, dest_size // bss end
mov tmp, #0
@4:
cmp dest, dest_end
strcc tmp, [dest], #4
bcc @4
beq @2
//---- fill static static bss with 0
@fill_bss:
ldr dest, [ptable, #12] // BSS segment start
ldr dest_end, [ptable, #16] // BSS segment end
mov tmp, #0
@3:
cmp dest, dest_end
strcc tmp, [dest], #4
bcc @3
// r0 = _start_ModuleParams
b _start_AutoloadDoneCallback // Jump into the callback
}
/*---------------------------------------------------------------------------*
Name: _start_AutoloadDoneCallback
Description: hook for end of autoload (This is dummy target for DEBUGGER)
Arguments: argv: pointer for autoload parameters
argv[0] = SDK_AUTOLOAD_LIST
argv[1] = SDK_AUTOLOAD_LIST_END
argv[2] = SDK_AUTOLOAD_START
argv[3] = SDK_STATIC_BSS_START
argv[4] = SDK_STATIC_BSS_END
Returns: None.
*---------------------------------------------------------------------------*/
__declspec ( weak ) asm void _start_AutoloadDoneCallback( void* argv[] )
{
bx lr
}
//-----------------------------------------------------------------------
// システム制御コプロセッサ 初期化
//-----------------------------------------------------------------------
static asm void init_cp15(void)
{
// プロテクションユニット/キャッシュ/TCM ディセーブル
mrc p15, 0, r0, c1, c0, 0
ldr r1, =HW_C1_ICACHE_ENABLE | HW_C1_DCACHE_ENABLE \
| HW_C1_ITCM_ENABLE | HW_C1_DTCM_ENABLE \
| HW_C1_ITCM_LOAD_MODE | HW_C1_DTCM_LOAD_MODE \
| HW_C1_LD_INTERWORK_DISABLE \
| HW_C1_PROTECT_UNIT_ENABLE
bic r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
// キャッシュ無効化
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 // 命令キャッシュ
mcr p15, 0, r0, c7, c6, 0 // データキャッシュ
// ライトバッファ エンプティ待ち
mcr p15, 0, r0, c7, c10, 4
/*
; Region G: BACK_GROUND: Base = 0x0, Size = 4GB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 0: IO_VRAM: Base = 0x04000000, Size = 64MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 1Rel: MAIN_MEM: Base = 0x02000000, Size = 4MB, I:Cach Buf / D:Cach Buf, I:RW / D:RW
; Region 1Dbg: MAIN_MEM: Base = 0x02000000, Size = 8MB, I:Cach Buf / D:Cach Buf, I:RW / D:RW
; Region 2Rel: SOUND_DATA: Base = 0x02380000, Size = 512KB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 2D4M: SOUND_DATA: Base = 0x02300000, Size = 1MB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 2D8M: SOUND_DATA: Base = 0x02600000, Size = 2MB, I:NC NB / D:NC NB, I:NA / D:NA
; Region 3: CARTRIDGE: Base = 0x08000000, Size = 128MB, I:NC NB / D:NC NB, I:NA / D:RW
; Region 4: DTCM: Base = SOUND_DATA, Size = 16KB, I:NC NB / D:NC NB, I:NA / D:RW
; Region 5: ITCM: Base = 0x01000000, Size = 16MB, I:NC NB / D:NC NB, I:RW / D:RW
; Region 6: BIOS: Base = 0xffff0000, Size = 32KB, I:Cach NB / D:Cach NB, I:RO / D:RO
; Region 7: SHARE_WORK: Base = 0x027ff000, Size = 4KB, I:NC NB / D:NC NB, I:NA / D:RW
;(Region 7: DBG_RESERVE: Base = 0x02700000, Size = 1MB, I:NC NB / D:NC NB, I:RW / D:RW)
*/
#define SET_PROTECTION_A( id, adr, siz ) ldr r0, =(adr|HW_C6_PR_##siz|HW_C6_PR_ENABLE)
#define SET_PROTECTION_B( id, adr, siz ) mcr p15, 0, r0, c6, id, 0
#define REGION_BIT(a,b,c,d,e,f,g,h) (((a)<<0)|((b)<<1)|((c)<<2)|((d)<<3)|((e)<<4)|((f)<<5)|((g)<<6)|((h)<<7))
#define REGION_ACC(a,b,c,d,e,f,g,h) (((a)<<0)|((b)<<4)|((c)<<8)|((d)<<12)|((e)<<16)|((f)<<20)|((g)<<24)|((h)<<28))
#define NA 0
#define RW 1
#define RO 5
//
// メモリリージョン初期化
//
//---- I/O レジスタ & VRAM 等
SET_PROTECTION_A( c0, HW_IOREG, 64MB )
SET_PROTECTION_B( c0, HW_IOREG, 64MB )
//---- メインメモリ
SET_PROTECTION_A( c1, HW_MAIN_MEM_MAIN, 4MB )
SET_PROTECTION_B( c1, HW_MAIN_MEM_MAIN, 4MB )
/* //---- サウンドデータ領域 // SYSM changed.
#if HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x1000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 4KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 4KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x2000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 8KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 8KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x4000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 16KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 16KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x8000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 32KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 32KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x10000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 64KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 64KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x20000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 128KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 128KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x40000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 256KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 256KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x80000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 512KB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 512KB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x100000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 1MB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 1MB )
#elif HW_MAIN_MEM_SUB_SIZE+HW_MAIN_MEM_SHARED_SIZE == 0x200000
SET_PROTECTION_A( c2, HW_MAIN_MEM_SUB, 2MB )
SET_PROTECTION_B( c2, HW_MAIN_MEM_SUB, 2MB )
#else
#pragma message(ERROR: Size unmatch HW_MAIN_MEM_SUB_SIZE)
#endif
*/
//---- カートリッジ又は他の用途
// CPU 内部ワーク RAM 等
SET_PROTECTION_A( c3, HW_CTRDG_ROM, 128MB )
SET_PROTECTION_B( c3, HW_CTRDG_ROM, 128MB )
//---- データ TCM
// + CPU 内部ワーク RAM の場合あり
//#if (HW_DTCM & 0x3FFF) != 0
//#pragma message(ERROR: HW_DTCM need to be aligned 16KB!)
//#endif
// SET_PROTECTION_A( c4, HW_DTCM, 16KB )
ldr r0, =SDK_AUTOLOAD_DTCM_START
orr r0, r0, #HW_C6_PR_16KB
orr r0, r0, #HW_C6_PR_ENABLE
SET_PROTECTION_B( c4, HW_DTCM, 16KB )
//---- 命令 TCM
// データ TCM より優先が高い、メインメモリ領域までのイメージ
SET_PROTECTION_A( c5, HW_ITCM_IMAGE, 16MB )
SET_PROTECTION_B( c5, HW_ITCM_IMAGE, 16MB )
//---- BIOS
SET_PROTECTION_A( c6, HW_BIOS, 32KB )
SET_PROTECTION_B( c6, HW_BIOS, 32KB )
//---- SHARED CPU 間通信ワーク領域
SET_PROTECTION_A( c7, HW_MAIN_MEM_SHARED, 4KB )
SET_PROTECTION_B( c7, HW_MAIN_MEM_SHARED, 4KB )
#if HW_MAIN_MEM_SHARED_SIZE != 0x1000
#pragma message(ERROR: Size unmatch HW_MAIN_MEM_SHARED_SIZE)
#endif
//
// 命令TCM 設定
//
mov r0, #HW_C9_TCMR_32MB
mcr p15, 0, r0, c9, c1, 1
//
// データTCM 設定
//
ldr r0, =INITi_HW_DTCM
orr r0, r0, #HW_C9_TCMR_16KB
mcr p15, 0, r0, c9, c1, 0
//
// 命令キャッシュ イネーブル (リージョン設定)
// 1: MAIN_MEM
// 6: BIOS
//
mov r0, #REGION_BIT(0,1,0,0,0,0,1,0)
mcr p15, 0, r0, c2, c0, 1
//
// データキャッシュ イネーブル (リージョン設定)
// 1: MAIN_MEM
// 6: BIOS
//
mov r0, #REGION_BIT(0,1,0,0,0,0,1,0)
mcr p15, 0, r0, c2, c0, 0
//
// ライトバッファ イネーブル(リージョン設定)
// 1: MAIN_MEM
//
mov r0, #REGION_BIT(0,1,0,0,0,0,0,0)
mcr p15, 0, r0, c3, c0, 0
//
// 命令アクセス許可 (リージョン設定)
// IO_VRAM : RW
// MAIN_MEM_MAIN : RW
// MAIN_MEM_SUB : NA
// CTRDG : NA
// DTCM : NA
// ITCM : RW
// BIOS : RO
// SHARED : NA
//
ldr r0, =REGION_ACC(RW,RW,NA,NA,NA,RW,RO,NA)
mcr p15, 0, r0, c5, c0, 3
//
// データアクセス許可(リージョン設定)
// IO_VRAM : RW
// MAIN_MEM_MAIN : RW
// MAIN_MEM_SUB : NA
// CTRDG : RW
// DTCM : RW
// ITCM : RW
// BIOS : RO
// SHARED : RW
//
ldr r0, =REGION_ACC(RW,RW,NA,RW,RW,RW,RO,RW)
mcr p15, 0, r0, c5, c0, 2
//
// システム制御コプロセッサ マスター設定
//
mrc p15, 0, r0, c1, c0, 0
ldr r1,=HW_C1_ICACHE_ENABLE | HW_C1_DCACHE_ENABLE | HW_C1_CACHE_ROUND_ROBIN \
| HW_C1_ITCM_ENABLE | HW_C1_DTCM_ENABLE \
| HW_C1_SB1_BITSET | HW_C1_EXCEPT_VEC_UPPER \
| HW_C1_PROTECT_UNIT_ENABLE
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
bx lr
}
/*---------------------------------------------------------------------------*
Name: NitroStartUp
Description: hook for user start up
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
__declspec ( weak ) void NitroStartUp( void )
{
}

View File

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: gameBoot.c
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.h>
#include <sysmenu/mmap.h>
// define data-------------------------------------------------------
#define C1_DTCM_ENABLE 0x00010000 // データTCM イネーブル
#define C1_EXCEPT_VEC_UPPER 0x00002000 // 例外ベクタ 上位アドレス(こちらに設定して下さい)
#define C1_SB1_BITSET 0x00000078 // レジスタ固定ビット列後期アボートモデル、DATA32構成シグナル制御、PROG32構成シグナル制御、ライトバッファイネーブル
#define INITi_HW_DTCM SDK_AUTOLOAD_DTCM_START
// extern data-------------------------------------------------------
// from LCF
extern u32 SDK_IRQ_STACKSIZE[];
// function's prototype----------------------------------------------
void ReturnFromMain(void);
void ResetCP15(void);
void ClearBankregAndStack(void);
void CpuClear32Byte(void);
void BootFuncEnd(void);
// global variables--------------------------------------------------
// static variables--------------------------------------------------
// const data--------------------------------------------------------
#include <twl/code32.h> // このソースはデフォルトではARMでコンパイルされる。
//-----------------------------------------------------------------------
// メインルーチンからのリターン
//-----------------------------------------------------------------------
/*
ReturnFromMainをRamの後方にコピーする方法がReturnFromMainアドレスから
   (BootFuncEnd - ReturnFromMain)
   
   
*/
asm void ReturnFromMain(void)
{
//---------------------------------------
// データキャッシュを全て無効に。DC_InvalidateAllを抜き出して実装
//---------------------------------------
mov r0, #0
mcr p15, 0, r0, c7, c6, 0
//---------------------------------------
// ARM7との同期をとるsubp_stateが2になるのを待って、mainp_stateを2にする。
//---------------------------------------
ldr r1, =REG_SUBPINTF_ADDR
@0 ldrh r0, [r1]
and r0, r0, #0x000f
cmp r0, #0x0002
bne @0
mov r0, #0x0200
strh r0, [r1]
//---------------------------------------
// ISデバッガ動作フラグの格納
//---------------------------------------
#ifdef __IS_DEBUGGER_BUILD
ldr r3, =HW_MAIN_MEM_EX_END
sub r0, r3, #0x400
ldrh r11, [r0, #0x14] // r11 = GetMovedInfoFromIPL1Addr()->isOnDebugger
#endif
//---------------------------------------
// ARM7との同期をとるsubp_stateが1になるのを待って、mainp_stateを1にする。
//---------------------------------------
ldr r1, =REG_SUBPINTF_ADDR
@1 ldrh r0, [r1]
and r0, r0, #0x000f
cmp r0, #0x0001
bne @1
mov r0, #0x0100
strh r0, [r1]
//---------------------------------------
// バンクレジスタ&スタッククリア
//---------------------------------------
bl ClearBankregAndStack
//---------------------------------------
// プロテクションユニットの解除
//---------------------------------------
bl ResetCP15
//---------------------------------------
// ARM7との最終同期をとる(subp_stateが0になるのを待って、mainp_stateを0にする
//---------------------------------------
ldr r1, =REG_SUBPINTF_ADDR
@2 ldrh r0, [r1]
and r0, r0, #0x000f
cmp r0, #0x0001
beq @2
ldr r3, =REG_VCOUNT_ADDR // Vカウンタを全IPL2バージョンで同一値(=0)でアプリに引き渡すようにする。
@3 ldrh r0, [r3]
cmp r0, #0
bne @3
// mov r0, #0 // R0に読んだVカウント値が"0"なので、これはいらない
strh r0, [r1]
//---------------------------------------
// R11の値をもとにブートアドレス取得
//---------------------------------------
ldr r3, =HW_MAIN_MEM_EX_END // ゲーム・エントリポイント 獲得
ldr r12, [r3, #-(0x200 - 0x24)] // rmhp->arm9->entryAddr
mov lr, r12
#ifdef __IS_DEBUGGER_BUILD
cmp r11, #1 // if (!GetMovedInfoFromIPL1Addr()->isOnDebugger)
ldreq r12, [r3, #-(0x200 - 0x168)] // デバッガ・エントリポイント 獲得
#endif
//---------------------------------------
// 汎用レジスタクリア
//---------------------------------------
ldr r11, =INITi_HW_DTCM // クリアしたDTCMからデータを読み出して、汎用レジスタをクリアする。
ldmia r11, {r0-r10}
mov r11, #0
//---------------------------------------
// ゲームブート
//---------------------------------------
bx r12
}
//-----------------------------------------------------------------------
// システム制御コプロセッサ リセット
//-----------------------------------------------------------------------
asm void ResetCP15(void)
{
// プロテクションユニットキャッシュITCM無効。DTCMは有効スタックをクリアするため
ldr r0, = C1_DTCM_ENABLE | C1_EXCEPT_VEC_UPPER | C1_SB1_BITSET
mcr p15, 0, r0, c1, c0, 0
// ITCMの割り当てを解除
mov r0, #0
mcr p15, 0, r0, c6, c5, 0
// DTCMの割り当てを解除
// mov r0,#0
// mcr p15, 0, r0, c9, c1, 0
// キャッシュ無効化
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 // 命令キャッシュ
mcr p15, 0, r0, c7, c6, 0 // データキャッシュ
// ライトバッファ エンプティ待ち
mcr p15, 0, r0, c7, c10, 4
bx lr
}
//-----------------------------------------------------------------------
// バンクレジスタ リセット スタック領域 クリア
//-----------------------------------------------------------------------
asm void ClearBankregAndStack(void)
{
mov r12, lr
#ifndef IPL2_ONLYMULTIBOOT
mov r0, #0xc0 | HW_PSR_SVC_MODE // SVCモードへ切り換え & IRQ/FIQ不許可
msr cpsr_cxsf, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
mov sp, r0 // SP のセット
mov lr, #0
msr spsr_csxf, lr
mov r0, #0xc0 | HW_PSR_IRQ_MODE // IRQモードへ切り換え & IRQ/FIQ不許可
msr cpsr_cxsf, r0
ldr r0, =INITi_HW_DTCM
add r0, r0, #0x3fc0
sub r0, r0, #HW_SVC_STACK_SIZE
mov sp, r0 // SP のセット
mov lr, #0
msr spsr_cxsf, lr
ldr r1, =SDK_IRQ_STACKSIZE
sub r1, r0, r1
mov r0, #0xc0 | HW_PSR_SYS_MODE // システムモードへ切り換え & IRQ/FIQ不許可
msr cpsr_cxsf, r0
sub sp, r1, #4 // SP のセット & 4byte for stack check code
#endif // IPL2_ONLYMULTIBOOT
ldr r0, =HW_ITCM // ITCMのクリア
mov r1, #HW_ITCM_SIZE
bl CpuClear32Byte
ldr r0, =INITi_HW_DTCM // スタックを含めたDTCMのクリア
mov r1, #HW_DTCM_SIZE
bl CpuClear32Byte
bx r12
}
// 32byte単位のメモリクリア r0 dstp,r1 byteSize
asm void CpuClear32Byte(void)
{
add r2, r0, r1 // 終了アドレスの算出
mov r1, r1, lsr #5 // サイズは32byte単位
mov r3, #0
mov r4, r3
mov r5, r3
mov r6, r3
mov r7, r3
mov r8, r3
mov r9, r3
mov r10, r3
@0 cmp r0, r2 // クリア終了?
stmltia r0!, {r3-r10}
blt @0
bx lr
}
void BootFuncEnd(void)
{
}
#include <twl/codereset.h> // ここまで。

View File

@ -0,0 +1,168 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: ninLogoFunc.c
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.h>
#include <sysmenu/rom_header.h>
#include <sysmenu/sysmenu_lib/ARM9/sysmenu_api.h>
// define data-----------------------------------------------------------
// extern data-----------------------------------------------------------
// function's prototype--------------------------------------------------
static void UnCompNintendoLogo2(u16 *NintendoLogoDatap, u16 *dstp, u32 *temp);
static void SVC_DiffUnFilter16_16_2(u16 *srcp,u16 *dstp);
static s32 MEMBm_InitFunc(const u8 *devicep, void *ramp, const void *paramp);
static s32 MEMBm_TerminateFunc(const u8 *devicep);
static u8 MEMBm_ByteStreamFunc(const u8 *devicep);
static u32 MEMBm_WordStreamFunc(const u8 *devicep);
// global variable-------------------------------------------------------
// static variable-------------------------------------------------------
static MIUnpackBitsParam Nin_UnPackBitsParam2 = { (8 * 8 / 2) * ( 7 * 2 ), 1, 4, 0, 0 };
// const data------------------------------------------------------------
static const u8 Nin_Char_Diff_Huff_Table2[]={
0x24,0xd4,0x00,0x00,
0x0f,0x40,0x00,0x00,0x00,0x01,0x81,0x82,0x82,0x83,0x0f,0x83,0x0c,0xc3,0x03,0x83,
0x01,0x83,0x04,0xc3,0x08,0x0e,0x02,0xc2,0x0d,0xc2,0x07,0x0b,0x06,0x0a,0x05,0x09,
};
const MIReadStreamCallbacks memb_ifp2={
MEMBm_InitFunc,
MEMBm_TerminateFunc,
MEMBm_ByteStreamFunc,
NULL,
MEMBm_WordStreamFunc,
};
// function's description--------------------------------------------
// Nintendoロゴデータの展開ルーチンOBJ2Dマップモードで展開
// ※tempBuffpには、0x700byte必要です。
void SYSM_LoadNintendoLogo2D( u16 *ninLogoDatap, u16 *dstp, u16 color, u32 *tempBuffp )
{
u32 work[ 0x100 / sizeof(u32) ];
Nin_UnPackBitsParam2.destOffset = color - 1;
UnCompNintendoLogo2( ninLogoDatap, (u16 *)tempBuffp, work );
MI_CpuCopyFast( (u16 *)( (u32)tempBuffp + 0 ), dstp + 0x0000 / sizeof(u16), 0x1a0 );
MI_CpuCopyFast( (u16 *)( (u32)tempBuffp + 0x1a0), dstp + 0x0400 / sizeof(u16), 0x1a0 );
}
void SYSM_LoadNintendoLogo1D( u16 *ninLogoDatap, u16 *dstp, u16 color, u32 *tempBuffp )
{
u32 work[ 0x100 / sizeof(u32) ];
Nin_UnPackBitsParam2.destOffset = color - 1;
UnCompNintendoLogo2( ninLogoDatap, (u16 *)tempBuffp, work );
MI_CpuCopyFast( (u16 *)tempBuffp, dstp, 0x340 );
}
/* UnCompNintendoLogo2ワーク内訳
dstp(0x700) temp(0x100)
Nintendoロゴ 0x0c0
0x200
0x0d0
diff後のデータ 0x0d0
UnpackBits後のデータ 0x700
*/
// Nintendoロゴ展開ルーチン (r0=ロゴ圧縮データ r1=展開先アドレス)
#include <twl/code16.h>
static asm void UnCompNintendoLogo2(u16 *NintendoLogoDatap, u16 *dstp, u32 *temp)
{
push {r0-r2,r4, lr}
ldr r0, =Nin_Char_Diff_Huff_Table2
mov r1, r2 // r1 <- temp
mov r4, r1 // r4 <- temp
mov r2, #36
bl MIi_CpuCopy16 // Nintendoロゴの圧縮テーブル部分のみをコピーしてくる
ldr r0, [sp, #0] // r0 <- NintendoLogoDatap
mov r2, #36
add r1, r4, r2 // r1 <- temp + 36
mov r2, #NINTENDO_LOGO_LENGTH
bl MIi_CpuCopy16 // NintendoLogoDatapからNintendoロゴデータ本体をコピーしてくる
mov r0, r4 // r0 <- temp
ldr r1, [sp, #4] // r1 <- dstp
mov r2, #1
lsl r2, r2, #8
add r2, r2, r1 // r2 <- dstp + 0x100
ldr r3, =memb_ifp2 // r3 <- memb_ifp2
bl SVC_UncompressHuffmanFromDevice // ハフマン展開
ldr r0, [sp, #4]
ldr r2, =0x0000d082
str r2, [r0,#0]
mov r1, r4 // temp
bl SVC_DiffUnFilter16_16_2 // Diff展開
mov r0, r4 // temp
ldr r1, [sp, #4] // dstp
ldr r2, =Nin_UnPackBitsParam2
bl SVC_UnpackBits // ビット展開
pop {r0-r2,r4, pc}
}
// 差分フィルタ展開システムコール16Bit→16Bit (r0=Srcp, r1=Destp)
static asm void SVC_DiffUnFilter16_16_2(u16 *srcp,u16 *dstp)
{
swi 24
bx lr
}
#include <twl/codereset.h>
// ============================================================================
// バイトアクセス可能メモリ用アクセスルーチン群
// ============================================================================
static s32 MEMBm_InitFunc(const u8 *devicep, void *ramp, const void *paramp)
{
#pragma unused(ramp)
if(paramp) return (s32)MEMBm_WordStreamFunc(devicep);
else return 0;
}
static s32 MEMBm_TerminateFunc(const u8 *devicep)
{
#pragma unused(devicep)
return 0;
}
static u8 MEMBm_ByteStreamFunc(const u8 *devicep)
{
return *devicep;
}
static u32 MEMBm_WordStreamFunc(const u8 *devicep)
{
return *(u32 *)devicep;
}

View File

@ -0,0 +1,582 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: nitroSettingsEx.c
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.h>
#include <sysmenu/machineSettings/common/nitroSettings.h>
#include "spi.h"
#ifndef USED_COMPONENT
#include <sysmenu/sysmenu_work.h>
#endif
// define data----------------------------------------------------------
#define NCD_EX_FORCE_ENABLE // このスイッチを定義すると、SYSMバージョンに関わらず強制的にNitroConfigDataExが有効になる。
// ※実機上では、このフラグのON,OFFに関係なく正常動作するが、アプリビルドをデバッガや他実機で動作させる際に、ここがONでないとダメ。
// 読み込まれていないNCDEXをリードして死亡してしまうので注意。
#define SAVE_COUNT_MAX 0x0080 // NitroConfigData.saveCountの最大値
#define SAVE_COUNT_MASK 0x007f // NitroConfigData.saveCountの値の範囲をマスクする。(0x00-0x7f
#define NCD_NOT_CORRECT 0x00ff // NITRO設定データが読み出されていない or 有効なものがないことを示す。
#define NVRAM_RETRY_NUM 8 // NVRAMリトライ回数
// NVRAMステータスレジスタ値
#define SR_WIP 0x01 // 0:READY 1:ライト、イレース中
#define SR_WEN 0x02 // 0:ライト禁止 1:ライト許可
#define SR_EER 0x20 // 1:イレースエラー発生SANYO製FLASHのみ
// NVRAM関連送信コマンドステート
static enum NvramCommState{
COMM_READY = 0,
COMM_RD,
COMM_WE,
COMM_WR,
COMM_RDSR_WE,
COMM_RDSR_WR,
COMM_SRST
}NvramCommState;
// SYSMヘッダ情報
typedef struct SYSMHeader {
u16 bm_arm9_rom_addr;
u16 bm_arm7_rom_addr;
u16 bm_crc16;
u16 ipl2_crc16;
u8 ipl2_key[4];
u16 ipl2_arm9_rom_addr;
u16 ipl2_arm9_ram_addr;
u16 ipl2_arm7_rom_addr;
u16 ipl2_arm7_ram_addr;
u16 ipl2_arm9_romOffsetUnit:3;
u16 ipl2_arm9_ramOffsetUnit:3;
u16 ipl2_arm7_romOffsetUnit:3;
u16 ipl2_arm7_ramOffsetUnit:3;
u16 ipl2_arm7_ramSelect:1;
u16 ipl2_header_ver:3;
u16 ipl2_data_rom_addr;
union {
struct {
u8 timestamp[5]; // SYSMタイムスタンプ [0]:分,[1]:時,[2]:日,[3]:月,[4]:年
u8 ipl2_type; // SYSMタイプ(nitroConfigData.hで定義のSYSM_TYPE...
u8 rsv[2];
} version;
u8 card_key[8];
} info;
u16 ncd_rom_addr;
union { // SYSMHeader.info.version.type == SYSM_TYPE_I_DISPLAY_JAPANもしくは
u16 sys_rsv_rom_addr; // SYSMHeader.info.version.timestamp >= 0x0502280851(SYSM_TYPE_NORMAL 3rd.以降)
u16 font_bncmp_offset; // ならば、font_bncmp_offset, font_bnfr_offsetが有効。
} rom_addr1; // ※なお、sys_rsv_rom_addr, app_rsv_rom_addrは、アドレスが変わったので
union { //  ここに入っている値は無効。ncd_rom_addrからの相対値で算出。
u16 app_rsv_rom_addr;
u16 font_bnfr_offset;
} rom_addr2;
u16 ipl2_data_crc16;
u8 pad[ 0x18 ]; // ※キャッシュラインに合わせるためのパディング。本来は必要なし。
} SYSMHeader; // 0x40bytes
// function's prototype-------------------------------------------------
static int NVRAMm_checkCorrectNCD(NCDStoreEx *ncdsp);
static BOOL NCD_CheckDataValue( NCDStoreEx *ncdsp );
static BOOL NVRAMm_ExecuteCommand( int nv_state, u32 addr, u16 size, u8 *srcp );
static void Callback_NVRAM(PXIFifoTag tag, u32 data, BOOL err);
// const data-----------------------------------------------------------
// global variables-----------------------------------------------------
NitroConfigDataEx ncdEx;
// static variables-----------------------------------------------------
static volatile BOOL nv_cb_occurred;
static volatile u16 nv_result;
static u16 ena_ncd_num = NCD_NOT_CORRECT;
static u16 next_saveCount;
static NCDStoreEx ncds[2] ATTRIBUTE_ALIGN(32);
#ifdef USED_COMPONENT
static SYSMHeader ipl2Header ATTRIBUTE_ALIGN(32);
static BOOL read_ipl2h = FALSE;
#endif
// function's description-----------------------------------------------
//----------------------------------------------------------------------
// SYSMヘッダ情報の読み出し
//----------------------------------------------------------------------
#ifndef USED_COMPONENT
// SYSM上での使用時
// SYSMタイプの取得
#define NCD_GetSYSMType() ( (u32)GetSYSMWork()->ipl2_type )
// NCD格納ROMアドレスの取得
#define NCD_GetNCDRomAddr() ( (u32)GetSYSMWork()->ncd_rom_adr )
#else
// コンポーネント上での使用時
// SYSMヘッダの読み出し
void NCD_ReadSYSMHeader( void )
{
if( !read_ipl2h ) {
OS_TPrintf( "SYSMHeader:%x\n", sizeof(SYSMHeader) );
DC_InvalidateRange( &ipl2Header, sizeof(SYSMHeader) );
while( !NVRAMm_ExecuteCommand( COMM_RD, 0, sizeof(SYSMHeader), (u8 *)&ipl2Header ) ) {}
read_ipl2h = TRUE;
}
}
// SYSMタイプの取得
u8 NCD_GetSYSMType( void )
{
NCD_ReadSYSMHeader();
return ipl2Header.info.version.ipl2_type;
}
// SYSMバージョンの取得
u8 *NCD_GetSYSMVersion( void )
{
NCD_ReadSYSMHeader();
return ipl2Header.info.version.timestamp;
}
// NCD格納ROMアドレスの取得
u32 NCD_GetNCDRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.ncd_rom_addr << NCD_ROM_ADDR_SHIFT );
}
// システム予約領域ROMアドレスの取得
u32 NCD_GetSysRsvRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.ncd_rom_addr << NCD_ROM_ADDR_SHIFT ) - NCD_SYS_RSV_SIZE;
}
// アプリ予約領域ROMアドレスの取得
u32 NCD_GetAppRsvRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.ncd_rom_addr << NCD_ROM_ADDR_SHIFT ) - NCD_SYS_RSV_SIZE - NCD_APP_RSV_SIZE;
}
// SYSMデータ格納ROMアドレスの取得
u32 NCD_GetSYSMDataRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.ipl2_data_rom_addr << NCD_ROM_ADDR_SHIFT );
}
// bncmpフォントデータ格納ROMアドレスの取得
u32 NCD_GetFontBncmpRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.rom_addr1.font_bncmp_offset << FONT_ROM_ADDR_SHIFT );
}
// bnfrフォントデータ格納ROMアドレスの取得
u32 NCD_GetFontBnfrRomAddr( void )
{
NCD_ReadSYSMHeader();
return (u32)( ipl2Header.rom_addr2.font_bnfr_offset << FONT_ROM_ADDR_SHIFT );
}
#endif
//----------------------------------------------------------------------
// NITRO設定データのリード
//----------------------------------------------------------------------
int NVRAMm_ReadNitroConfigData(NitroConfigData *dstp)
{
int result = 0;
NCDStoreEx *ncdsp = &ncds[ 0 ];
DC_InvalidateRange( ncdsp, sizeof(NCDStoreEx) * 2 );
// フラッシュからニ重化されているNITRO設定データを読み出す。
while( !NVRAMm_ExecuteCommand( COMM_RD, NCD_GetNCDRomAddr(), sizeof(NCDStoreEx), (u8 *)&ncdsp[0]) ) {}
while( !NVRAMm_ExecuteCommand( COMM_RD, NCD_GetNCDRomAddr() + SPI_NVRAM_PAGE_SIZE, sizeof(NCDStoreEx), (u8 *)&ncdsp[1]) ) {}
OS_TPrintf("NCD read addr=%08x\n", NCD_GetNCDRomAddr() );
// 読み出したデータのどちらが有効かを判定する。
if(NVRAMm_checkCorrectNCD(ncdsp)) {
next_saveCount = 1;
result = 1;
goto END; // 有効なデータがなければエラー終了。
}
next_saveCount = (u8)((ncdsp[ena_ncd_num].saveCount + 1) & SAVE_COUNT_MASK);
// 有効なNITRO設定データをバッファに転送
if(dstp!=NULL) {
SVC_CpuCopy( (void *)&ncdsp[ ena_ncd_num ].ncd, (void *)dstp, sizeof(NitroConfigData), 16);
SVC_CpuCopy( (void *)&ncdsp[ ena_ncd_num ].ncd_ex, (void *)&ncdEx, sizeof(NitroConfigDataEx), 16);
}
END:
return result;
}
//----------------------------------------------------------------------
// NITRO設定データのライト
//----------------------------------------------------------------------
void NVRAMm_WriteNitroConfigData( NitroConfigData *srcp )
{
NCDStoreEx *ncdsp = &ncds[ 0 ];
u16 size = sizeof(NCDStore);
u32 flash_addr;
int retry;
// まだNITRO設定データがリードされていなければ、リードを行って必要な情報を取得する。
if( ena_ncd_num == NCD_NOT_CORRECT ) {
if( NVRAMm_ReadNitroConfigData( NULL ) ) {
ena_ncd_num = 0; // 有効なデータがなければ"0"側にライトする。
}
}
// NCD のCRC、セーブカウント値、ライトアドレスの算出。
ncdsp->ncd = *srcp; // *GetNCDWork(); でも一緒やん。
ncdsp->ncd.version = NITRO_CONFIG_DATA_VERSION; // バージョンを現在のものに設定。
ncdsp->crc16 = SVC_GetCRC16( 0xffff, (const void *)&ncdsp->ncd, sizeof(NitroConfigData) );
ncdsp->saveCount = next_saveCount;
next_saveCount = (u8)( ( next_saveCount + 1 ) & SAVE_COUNT_MASK );
// NCD_EXのCRC算出。
#ifndef NCD_EX_FORCE_ENABLE
if( ( NCD_GetSYSMType() != SYSM_TYPE_NTR_WW ) && ( NCD_GetSYSMType() & SYSM_TYPE_NCD_EX_FLAG ) )
#endif
{
ncdsp->ncd_ex = *GetNCDExWork();
ncdsp->ncd_ex.version = NITRO_CONFIG_DATA_EX_VERSION; // バージョンを現在のものに設定。
ncdsp->crc16_ex = SVC_GetCRC16( 0xffff, (const void *)&ncdsp->ncd_ex, sizeof(NitroConfigDataEx) );
size = sizeof(NCDStoreEx); // ※書き込みサイズをNCDStoreExに拡張。
}
// NITRO設定データのライト
DC_FlushRange(ncdsp, sizeof(NCDStoreEx));
retry = NVRAM_RETRY_NUM;
while( retry-- ) {
ena_ncd_num ^= 0x01; // リトライの度に書き込みアドレスを切り替える。
flash_addr = NCD_GetNCDRomAddr() + ena_ncd_num * SPI_NVRAM_PAGE_SIZE;
OS_TPrintf("NCD write addr=%08x\n", flash_addr );
if( NVRAMm_ExecuteCommand( COMM_WE, flash_addr, size, (u8 *)ncdsp) ) {
OS_TPrintf("NVRAM Write succeeded.\n");
break;
}
SVC_WaitByLoop( 0x4000 );
OS_TPrintf("NVRAM Write retry = %d.\n", NVRAM_RETRY_NUM - retry );
}
}
//----------------------------------------------------------------------
// ミラーリングされているNITRO設定データのどちらが有効かを判定
//----------------------------------------------------------------------
static int NVRAMm_checkCorrectNCD(NCDStoreEx *ncdsp)
{
u16 i;
u16 ncd_valid = 0;
// 各ミラーデータのCRC & saveCount正当性チェック
for(i = 0; i < 2; i++) {
u16 crc;
BOOL invalid = FALSE;
crc = SVC_GetCRC16( 0xffff, (const void *)&ncdsp[i].ncd, sizeof(NitroConfigData) );
if( ( ncdsp[ i ].crc16 != crc ) // CRCが正しく、saveCount値が0x80以下で、かつバージョンが一致するデータを正当と判断。
|| ( ncdsp[ i ].ncd.version != NITRO_CONFIG_DATA_VERSION )
|| ( ncdsp[ i ].saveCount >= SAVE_COUNT_MAX ) ) {
OS_TPrintf("NCD crc error.\n");
invalid = TRUE;
}
// NCDExが有効なSYSMTypeならば、NCDExのCRCチェックを行う。
#ifndef NCD_EX_FORCE_ENABLE
if( ( NCD_GetSYSMType() != SYSM_TYPE_NTR_WW ) && ( NCD_GetSYSMType() & SYSM_TYPE_NCD_EX_FLAG ) )
#endif
{
crc = SVC_GetCRC16( 0xffff, (const void *)&ncdsp[i].ncd_ex, sizeof(NitroConfigDataEx) );
if( ( ncdsp[ i ].crc16_ex != crc )
|| ( ncdsp[ i ].ncd_ex.version != NITRO_CONFIG_DATA_EX_VERSION ) ) {
OS_TPrintf("NCDEx crc error.\n");
invalid = TRUE;
}
}
// NCD, NCDExのCRCが正しいなら、データの中身をチェック。
if( !invalid ) {
if( NCD_CheckDataValue( &ncdsp[ i ] ) ) {
ncd_valid |= 0x01 << i; // データがおかしい値でないかもチェック。
ena_ncd_num = i; // 有効なNCDのインデックスを切り替える。
}else {
invalid = TRUE;
}
}
if( ncd_valid & ( 0x01 << i ) ) {
OS_TPrintf("NCD mirror%d is valid.:saveCount = %d\n", i, ncdsp[i].saveCount);
}else {
OS_TPrintf("NCD mirror%d is invalid.\n", i);
}
}
if( ncd_valid == 0 ) {
return 1;
}else if( ncd_valid == 0x03 ) {
// ミラーリングされたNCDが両方ともに正当な場合、セーブカウント値が大きい方を有効とする。
u16 saveCount = (u8)( ( ncdsp[ 0 ].saveCount + 1 ) & SAVE_COUNT_MASK );
if( saveCount != ncdsp[ 1 ].saveCount ) {
ena_ncd_num = 0;
}
}
OS_TPrintf("use NCD mirror%d.:saveCount = %d\n", ena_ncd_num, ncdsp[ena_ncd_num].saveCount);
return 0;
}
// NITRO設定データの値が正しい値かチェック。 // FALSE:正しくない。TRUE正しい。
static BOOL NCD_CheckDataValue( NCDStoreEx *ncdsp )
{
NitroConfigData *ncdp = &ncdsp->ncd;
NitroConfigDataEx *ncdexp = &ncdsp->ncd_ex;
//ncdp->option;
// NCDのlanguageチェック
if( ~( LANG_BITMAP_WW & VALID_LANG_BITMAP ) & ( 0x0001 << ncdp->option.language ) ) {
OS_TPrintf("NCD: invalid language : org:%02d ex:%02d bitmap:%04x\n",
ncdp->option.language, ncdexp->language, ncdexp->valid_language_bitmap );
return FALSE;
}
// NCDExのlanguageチェックNCDExが有効なのは、下記のSYSMタイプのもの
#ifndef NCD_EX_FORCE_ENABLE
if( ( NCD_GetSYSMType() != SYSM_TYPE_NTR_WW ) && ( NCD_GetSYSMType() & SYSM_TYPE_NCD_EX_FLAG ) )
#endif
{
if( ( ~VALID_LANG_BITMAP & ( 0x0001 << ncdexp->language ) )
|| ( ncdexp->valid_language_bitmap != VALID_LANG_BITMAP ) ) {
OS_TPrintf("NCDEx: invalid language : org:%02d ex:%02d bitmap:%04x\n",
ncdp->option.language, ncdexp->language, ncdexp->valid_language_bitmap );
return FALSE;
}
}
//ncdp->owner;
// favoriteColorは4bitなので範囲外はない。
// birthday
if( ncdp->option.input_birthday ) {
if( ( ncdp->owner.birthday.month > 12 ) || ( ncdp->owner.birthday.day > 31 ) ) {
OS_TPrintf("NCD: invalid birthday : %02d/%02d\n", ncdp->owner.birthday.month, ncdp->owner.birthday.day );
return FALSE;
}
}
// nickname
if( ncdp->option.input_nickname ) {
if( ncdp->owner.nickname.length > NCD_NICKNAME_LENGTH ) {
OS_TPrintf("NCD: invalid nickname length : %02d\n", ncdp->owner.nickname.length );
return FALSE;
}
}
// comment
if( ncdp->owner.comment.length > NCD_COMMENT_LENGTH ) {
OS_TPrintf("NCD: invalid comment length : %02d\n", ncdp->owner.comment.length );
return FALSE;
}
//ncdp->alarm;
if( ( ncdp->alarm.hour > 23 ) || ( ncdp->alarm.minute > 59 ) ) {
OS_TPrintf("NCD: invalid alarm time : %02d:%02d\n", ncdp->alarm.hour, ncdp->alarm.minute );
return FALSE;
}
//ncdp->tp;
// TPキャリブレーション値は、TP_CalcCalibrateParamで値のチェックをしているので、チェックしない。
OS_TPrintf( "NCD: correct data.\n" );
return TRUE;
}
//----------------------------------------------------------------------
// NVRAMへのアクセスルーチン本体 ( nv_state <- COMM_RD or COMM_WE )
//----------------------------------------------------------------------
static BOOL NVRAMm_ExecuteCommand( int nv_state, u32 addr, u16 size, u8 *srcp )
{
OSTick start;
BOOL nv_sending = FALSE;
u8 *nvram_srp = (u8 *)&ncds[1];
PXI_SetFifoRecvCallback( PXI_FIFO_TAG_NVRAM , Callback_NVRAM );
while( 1 ) {
//---------------------------------------
// NVRAMコマンドを発行する
//---------------------------------------
if( !nv_sending ) {
nv_cb_occurred = FALSE;
switch( nv_state ) {
case COMM_RD:
nv_sending = SPI_NvramReadDataBytes( addr, size, srcp );
break;
case COMM_WE:
nv_sending = SPI_NvramWriteEnable();
break;
case COMM_WR:
nv_sending = SPI_NvramPageWrite( addr, size , srcp );
start = OS_GetTick();
break;
case COMM_RDSR_WE:
case COMM_RDSR_WR:
nv_sending = SPI_NvramReadStatusRegister( nvram_srp );
break;
case COMM_SRST:
nv_sending = SPI_NvramSoftwareReset();
break;
}
//---------------------------------------
// コマンド実行結果(コールバック発生)を待って結果を処理する
//---------------------------------------
}else { // nv_sending == TRUE
if( nv_cb_occurred == TRUE ) { // コールバック発生を待つ。
nv_sending = FALSE;
if( nv_result == SPI_PXI_RESULT_SUCCESS ) {
switch( nv_state ) {
case COMM_RD:
return TRUE;
case COMM_WE:
nv_state = COMM_RDSR_WE;
break;
case COMM_WR:
nv_state = COMM_RDSR_WR;
break;
case COMM_RDSR_WE:
case COMM_RDSR_WR:
DC_InvalidateRange( nvram_srp, 1 );
if( nv_state == COMM_RDSR_WE ) { // ライトイネーブル確認ステートなら
if( ( *nvram_srp & SR_WEN ) ) {
nv_state = COMM_WR;
}else {
OS_TPrintf("NVRAM ERR: Write Enable Invalid.\n");
return FALSE;
}
}else {
if( ( *nvram_srp & SR_WIP ) == 0 ) { // ライト/イレース終了
return TRUE;
}else {
if( ( *nvram_srp & SR_EER ) // SR_EERが立っていたらエラー
|| ( OS_TicksToMilliSeconds( OS_GetTick() - start ) > 4000 ) ) {
// コマンド発行から4秒経過したらエラー※保険
OS_TPrintf( "NVRAM SR : %02x\n", *nvram_srp );
nv_state = COMM_SRST;
}else {
SVC_WaitByLoop( 0x4000 );
}
}
}
break;
case COMM_SRST:
OS_TPrintf("NVRAM ERR: PageErase Timeout and SoftReset.\n");
return FALSE;
}
}else { // nv_result != SPI_PXI_RESULT_SUCCESS
OS_TPrintf("NVRAM ERR: NVRAM PXI command failed.\n");
return FALSE;
}
}
}
}
}
//----------------------------------------------------------------------
// コールバック
//----------------------------------------------------------------------
static void Callback_NVRAM( PXIFifoTag tag, u32 data, BOOL err )
{
#pragma unused(tag)
u16 command = (u16)( ( ( data & SPI_PXI_DATA_MASK ) & 0x7f00 ) >> 8 );
nv_result = (u16)( data & 0x00ff );
nv_cb_occurred = TRUE; // コールバック発生フラグTRUE
if( err ) {
OS_TPrintf("NVRAM-ARM9: Received PXI data is error.\n");
nv_result = 0x00ff;
}
switch(command){ // コマンド名表示
case SPI_PXI_COMMAND_NVRAM_READ:
OS_TPrintf("NVRAM-ARM9:ReadDataBytes");
break;
case SPI_PXI_COMMAND_NVRAM_WREN:
OS_TPrintf("NVRAM-ARM9:WriteEnable");
break;
case SPI_PXI_COMMAND_NVRAM_PW:
OS_TPrintf("NVRAM-ARM9:PageWrite");
break;
case SPI_PXI_COMMAND_NVRAM_RDSR:
OS_TPrintf("NVRAM-ARM9:ReadStatusRegister");
break;
case SPI_PXI_COMMAND_NVRAM_WRDI:
OS_TPrintf("NVRAM-ARM9:WriteDisable");
break;
case SPI_PXI_COMMAND_NVRAM_PE:
OS_TPrintf("NVRAM-ARM9:PageErase");
break;
case SPI_PXI_COMMAND_NVRAM_SR:
OS_TPrintf("NVRAM-ARM9:SoftwareReset");
break;
default:
OS_TPrintf("NVRAM-ARM9:?????");
break;
}
if( nv_result != SPI_PXI_RESULT_SUCCESS ) {
OS_TPrintf(" Error! ->%x", nv_result );
}
OS_TPrintf("\n");
}

View File

@ -0,0 +1,253 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_card.c
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 <sysmenu/sysmenu_lib/ARM9/sysmenu_api.h>
#include "sysmenu_card.h"
typedef enum {
CARD_NOT_DETECTING = 0,
CARD_DETECTING
} CARDPullStatus;
typedef struct SYSMCardPullWork
{
CARDPullStatus pullStatus;
u32 cardCnt;
u16 lockID;
u16 detectPullOut;
} SYSMCardPullWork;
static SYSMCardPullWork cpw;
// 内部関数
void SYSMi_InitCardPulledOut(void);
BOOL SYSMi_IsDetectableCardPulledOut(void);
void SYSMi_StartReadCardID(void);
void SYSMi_ReadCardPage(void *romp, void *ramp, s32 size);
static void SYSMi_SetCardOp(const u32 *op);
//----------------------------------------------------------------------
// カード抜け検出初期化
//----------------------------------------------------------------------
void SYSMi_InitCardPulledOut(void)
{
cpw.lockID = (u16 )OS_GetLockID();
cpw.cardCnt = *(vu32 *)MROMCNT_GAME_BUF;
}
//----------------------------------------------------------------------
// カード抜け検出
//----------------------------------------------------------------------
BOOL SYSM_IsCardPulledOut(void)
{
if (SYSMi_IsDetectableCardPulledOut() == FALSE) return FALSE;
switch (cpw.pullStatus) {
case CARD_NOT_DETECTING:
if (OS_TryLockCard( cpw.lockID ) == OS_LOCK_SUCCESS )
{
SYSMi_StartReadCardID();
cpw.pullStatus = CARD_DETECTING;
}
break;
case CARD_DETECTING:
if (SYSMi_IsCardDataReady()) {
u32 cardID = *(vu32 *)REG_CARD_DATA;
if (cardID != GetSYSMWork()->nCardID
&& SYSM_IsNITROCard())
{
cpw.detectPullOut = TRUE;
}
(void)OS_UnlockCard( cpw.lockID );
cpw.pullStatus = CARD_NOT_DETECTING;
}
break;
}
return cpw.detectPullOut;
}
//----------------------------------------------------------------------
// カード抜け検出終了処理
//----------------------------------------------------------------------
void SYSM_FinalizeCardPulledOut(void)
{
while (SYSM_IsDetectingCardPulledOut()) {
(void)SYSM_IsCardPulledOut();
}
}
//----------------------------------------------------------------------
// カード抜け検出処理中か
//----------------------------------------------------------------------
BOOL SYSM_IsDetectingCardPulledOut(void)
{
return (cpw.pullStatus == CARD_DETECTING);
}
//----------------------------------------------------------------------
// カード抜け検出の準備ができているか
//----------------------------------------------------------------------
BOOL SYSMi_IsDetectableCardPulledOut(void)
{
return (SYSM_GetBootFlag() & BFLG_LOAD_CARD_COMPLETED ) ? TRUE : FALSE;
}
//----------------------------------------------------------------------
// カードID読み込み開始
//----------------------------------------------------------------------
void SYSMi_StartReadCardID(void)
{
u32 op[2];
op[0] = 0; // コマンド設定
op[1] = MROMOP_G_READ_ID;
SYSMi_SetCardOp( op );
// コントロール設定
*(vu32 *)REG_CARDCNT = cpw.cardCnt
| CARD_READ_MODE | CARD_STATUS
| CARD_START | CARD_RESET_HI;
}
//----------------------------------------------------------------------
// カードID読み込み
//----------------------------------------------------------------------
u32 SYSMi_ReadCardID(void)
{
u32 op[2];
op[0] = 0; // コマンド設定
op[1] = MROMOP_G_READ_ID;
SYSMi_SetCardOp( op );
// コントロール設定
*(vu32 *)REG_CARDCNT = *(vu32 *)MROMCNT_GAME_BUF
| CARD_READ_MODE | CARD_STATUS
| CARD_START | CARD_RESET_HI;
SYSMi_WaitCardData();
return *(vu32 *)REG_CARD_DATA;
}
//----------------------------------------------------------------------
// カードデータ同期読み込み
//----------------------------------------------------------------------
void SYSM_ReadCard(void *romp, void *ramp, s32 size)
{
s32 restSize = size;
s32 blockSize = MROM_PAGE_SIZE;
while (restSize > 0) { // ブロック分割読み込み
if (restSize >= MROM_PAGE_SIZE) { size = MROM_PAGE_SIZE;
} else { size = restSize;
}
SYSMi_ReadCardPage(romp, ramp, size);
(u8 *)romp += size;
(u8 *)ramp += size;
restSize -= size;
}
}
//----------------------------------------------------------------------
// ページ読み込み
//----------------------------------------------------------------------
void SYSMi_ReadCardPage(void *romp, void *ramp, s32 size)
{
{ u32 op[2];
op[0] = (u32 )romp <<24; // コマンド設定
op[1] = MROMOP_G_READ_PAGE | (u32 )romp >>8;
SYSMi_SetCardOp( op );
}
// ページリード
{ void *ramEndp;
u32 cardCntTmp;
*(vu32 *)REG_CARDCNT = *(vu32 *)MROMCNT_GAME_BUF // コントロール設定
| CARD_READ_MODE | CARD_1_PAGE
| CARD_START | CARD_RESET_HI;
ramEndp = (u8 *)ramp + size; // 格納終了アドレス算出
do { // CPU読み込み
cardCntTmp = *(vu32 *)REG_CARDCNT;
if (cardCntTmp & CARD_DATA_READY) {
u32 dataTmp = *(vu32 *)REG_CARD_DATA;
if (ramp < ramEndp)
*((vu32 *)ramp) = dataTmp; // 指定サイズまで格納(後続データは読み捨て)
((vu32 *)ramp)++;
}
} while (cardCntTmp & CARD_START);
}
}
//----------------------------------------------------------------------
// コマンド設定
//----------------------------------------------------------------------
static void SYSMi_SetCardOp(const u32 *op)
{
int i;
*(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM // マスターイネーブル
| CARDMST_ENABLE;
for (i=0; i<2; i++) { // コマンド設定
u32 opTmp = op[1 - i];
vu8 *opDestBasep = (vu8 *)(REG_CARD_CMD + i*4);
opDestBasep[0] = (u8 )(opTmp >>24);
opDestBasep[1] = (u8 )(opTmp >>16);
opDestBasep[2] = (u8 )(opTmp >>8);
opDestBasep[3] = (u8 )(opTmp >>0);
}
}

View File

@ -0,0 +1,721 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_lib.c
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.h>
#include <sysmenu.h>
#include "sysmenu_define.h"
#include "sysmenu_card.h"
#include "spi.h"
#include "mb_child.h"
// define data-----------------------------------------------------------------
#define SCREEN_RED 0
#define SCREEN_YELLOW 1
typedef struct BannerCheckParam {
u8 *srcp;
u32 size;
}BannerCheckParam;
typedef struct TitleProperty { // この情報は、ランチャー時には認証通ってないけど、起動時には認証通すので大丈夫だろう。
u64 titleID; // アプリケーション識別ID
u32 platform; // NTR, TWL (HYBLIDはTWLを返す
void *pBanner; // 固定長フォーマットなら偽造されても大丈夫だろう。
}TitleProperty;
typedef enum AuthState {
AUTH_PROCESSING = 0,
AUTH_RESULT_SUCCEEDED = 1,
AUTH_RESULT_TITLE_POINTER_ERROR = 2,
AUTH_RESULT_AUTHENTICATE_FAILED = 3,
AUTH_RESULT_ENTRY_ADDRESS_ERROR = 4
}AuthState;
// extern data-----------------------------------------------------------------
extern void ReturnFromMain( void );
extern void BootFuncEnd( void );
FS_EXTERN_OVERLAY( ipl2_data );
FS_EXTERN_OVERLAY( bm_mainp );
// function's prototype-------------------------------------------------------
static BOOL SYSMi_CheckTitlePointer( TitleProperty *pBootTitle );
AuthState SYSM_AuthAndLoadTitle( TitleProperty *pBootTitle );
void SYSM_Finalize( void );
static void INTR_SubpIRQ( void );
static void SYSMi_CheckCardLoadAddressAndSize( void );
static void LoadRomRegSizeAdjust( CARDRomRegion *romRegp, u32 load_limit_lo, u32 load_limit_hi );
static void SYSMi_ReadyBootNitroGame( void );
static BOOL SYSMi_CheckARM7LoadNITROCard( void );
static void SYSMi_MainpRegisterAndRamClear( BOOL isPlatformTWL );
static void ClearMemory( int addr1, int addr2 );
static void SYSMi_CopyInfoFromIPL1( void );
static void SYSMi_ReadNTRSetting( void );
static void SYSMi_ReadTWLSetting( void );
static void SYSMi_VerifyNTRSetting( void );
static void SYSMi_CheckEntryAddress( void );
static void SYSMi_CaribrateTP( void );
static void SYSMi_WriteAdjustRTC( void );
static BOOL SYSMi_SendMessageToARM7( u32 msg );
static BOOL SYSMi_CheckNitroCardRightly( void );
static int SYSMi_ExistCard( void );
static u32 SYSMi_SelectBootType( void );
static void SYSMi_DispInitialDebugData( void );
static void SYSMi_DispDebugData( void );
static void DispSingleColorScreen( int mode );
static void SYSMi_ReadCardBannerFile( void );
static void SYSMi_CheckCardCloneBoot( void );
// global variable-------------------------------------------------------------
#ifdef __SYSM_DEBUG
SharedWork *swp; // デバッガでのIPL1SharedWorkのウォッチ用
SYSM_work *pSysm; // デバッガでのSYSMワークのウォッチ用
NitroConfigData *ncdp; // デバッガでのNCデータ のウォッチ用
#endif
// static variable-------------------------------------------------------------
static BOOL s_isBanner = FALSE;
static BannerFile s_bannerBuf;
// const data------------------------------------------------------------------
static BannerCheckParam s_bannerCheckList[ BNR_VER_MAX ] = {
{ (u8 *)&s_bannerBuf.v1, sizeof( BannerFileV1 ) },
{ (u8 *)&s_bannerBuf.v2, sizeof( BannerFileV2 ) },
{ (u8 *)&s_bannerBuf.v3, sizeof( BannerFileV3 ) },
};
#ifdef __DEBUG_SECURITY_CODE
static GXRgb security_detection_color[] = { GX_RGB( 31, 0, 0 ),
GX_RGB( 31, 31, 0 ), };
#endif
// inline functions------------------------------------------------------------
static inline void DBG_SetRed(u32 y_pos)
{
*(u16 *)(HW_DB_BG_VRAM + 0xf000 + 0x20*2*y_pos) = (1<<12) | 0x100;
MI_CpuFill16(((u8 *)HW_DB_BG_VRAM + 0x20*0x100), 0x1111, 0x20);
}
// ============================================================================
// function's description
// ============================================================================
// SystemMenuの初期化
void SYSM_Init( void )
{
#ifdef __SYSM_DEBUG
pSysm = GetSYSMWork();
ncdp = GetNCDWork();
// SYSMi_DispInitialDebugData(); // 初期デバッグ情報表示
#endif /* __SYSM_DEBUG */
// WRAM設定はいる
// MI_SetMainMemoryPriority(MI_PROCESSOR_ARM7);
// MI_SetWramBank(MI_WRAM_ARM7_ALL);
SVC_CpuClearFast(0x0000, (u16 *)GetSYSMWork(), sizeof(SYSM_work)); // SYSMワークのクリア
// ※ISデバッガかどうかの判定。 BootROMからのパラメータ引渡し
}
// ARM7側の初期化待ち
BOOL SYSM_WaitARM7Init( void )
{
/* while( !( SYSM_GetBootFlag() & BFLG_ARM7_INIT_COMPLETED ) ) {
SVC_WaitByLoop(0x1000); // ARM7の初期化が終了するのを待つ。
}
*/
reg_OS_PAUSE |= REG_OS_PAUSE_CHK_MASK; // PAUSEレジスタのチェックフラグのセット
SYSMi_ReadNTRSetting(); // NOR からNTR本体設定データをリード
SYSMi_ReadTWLSetting(); // NANDからTWL本体設定データをリード
PMm_SetBackLightBrightness();
SYSMi_CaribrateTP(); // 読み出したTWL本体設定データをもとにTPキャリブレーション。
SYSMi_WriteAdjustRTC(); // 読み出したTWL本体設定データをもとにRTCクロック補正値をセット。
SYSMi_VerifyNTRSetting(); // NVRAMのNTR本体設定データをリードし、不一致箇所があればNTR側をリカバリ。
SYSMi_CheckCardCloneBoot(); // カードがクローンブートかチェック
SYSMi_ReadCardBannerFile(); // カードバナーファイルの読み出し。
// ==============================================================
// デバッガ対応コード
#ifdef __IS_DEBUGGER_BUILD
if( GetSYSMWork()->isOnDebugger ) {
if( !SYSM_IsDebuggerBannerViewMode() ){ // デバッガ上動作の場合は、この中でカードブートまでやってしまう。
( void )OS_EnableIrqMask( OS_IE_V_BLANK );
( void )OS_EnableIrq();
( void )OS_EnableInterrupts();
( void )GX_VBlankIntr( TRUE );
if( SYSMi_ExistCard() ) {
( void )SYSM_Main();
SYSM_SetBootFlag( BFLG_BOOT_CARD );
( void )SYSM_BootCARD();
SYSM_PermitToBootSelectedTarget();
while(1) {
OS_WaitIrq( 1, OS_IE_V_BLANK ); // Vブランク割込終了待ち
if( SYSM_Main() ) { // システムのメイン
return TRUE; // TRUEが帰ってきたらメインループからリターンカード起動
}
}
}
}
}else {
while( 1 ) {} // ISデバッガビルドでISデバッガが検出できなかったら停止。
}
#endif // __IS_DEBUGGER_BUILD
// ==============================================================
return FALSE;
}
// 指定タイトルがブート可能なポインタかチェック
static BOOL SYSMi_CheckTitlePointer( TitleProperty *pBootTitle )
{
#pragma unused( pBootTitle )
return TRUE;
}
// 指定タイトルの認証&ロード ※1フレームじゃ終わらん。
AuthState SYSM_AuthAndLoadTitle( TitleProperty *pBootTitle )
{
#pragma unused( pBootTitle )
// メインメモリのクリア
// DSダウンロードプレイの時は、ROMヘッダを退避する
// アプリロード
// アプリ認証
// エントリアドレスの正当性をチェックし、無効な場合は無限ループに入る。
SYSMi_CheckEntryAddress();
return AUTH_RESULT_SUCCEEDED;
}
// ブートのための終了処理
void SYSM_Finalize( void )
{
// ARM7へのブート通知
// レジスタ・RAMクリア
// ※ブート時にプロテクションユニットをOFFにしなければ、不正なアドレスでの起動を防げるのでは
u32 i;
// ブートの前準備
MI_CpuCopyFast( (void *)ReturnFromMain, (void *)RETURN_FROM_MAIN_ARM9_FUNCP, (u32)( (u32)BootFuncEnd - (u32)ReturnFromMain ) );
DC_StoreRange ( (void *)ReturnFromMain, 0x200 ); // ゲームブート時の最終処理をメインメモリの後ろの方にコピー※SYSM実行時のスタック上昇で破壊されないように、このタイミングでコピーする。
for( i = 0; i <= MI_DMA_MAX_NUM; i++ ) { // DMAの停止
MI_StopDma( i );
}
SYSM_FinalizeCardPulledOut(); // カード抜け検出終了処理
SYSMi_MainpRegisterAndRamClear( TRUE ); // レジスタRAMクリア
( void )GX_VBlankIntr(FALSE);
( void )OS_SetIrqFunction(OS_IE_SUBP, INTR_SubpIRQ);
( void )OS_SetIrqMask(OS_IE_SUBP); // サブプロセッサ割り込みのみを許可。
reg_PXI_SUBPINTF = SUBP_RECV_IF_ENABLE | 0x0f00; // ARM9ステートを "0x0f" に
GetSYSMWork()->mainp_state = MAINP_STATE_WAIT_BOOT_REQ;
// ※もうFIFOはクリア済みなので、使わない。
// ARM7からの通知待ち
OS_WaitIrq(1, OS_IE_SUBP); // SVC_WaitIntr(0,OS_IE_SUBP);から変更。
// 割り込みをクリアして最終ブートシーケンスへ。
reg_PXI_SUBPINTF &= 0x0f00; // サブプロセッサ割り込み許可フラグをクリア
( void )OS_DisableIrq();
( void )OS_SetIrqMask(0);
( void )OS_ResetRequestIrqMask( (u32)~0 );
}
#if 0
// NITRO起動をARM7に通知
BOOL SYSM_BootCard( void )
{ // Nintendoロゴチェックは、このタイミングで行う。
( void )SYSMi_SendMessageToARM7(MSG_BOOT_TYPE_CARD); // ARM7にカード起動を通知。
if( SYSM_CheckNinLogo( (u16 *)GetRomHeaderAddr()->nintendo_logo ) == FALSE
|| GetSYSMWork()->enableCardNormalOnly == TRUE ) { // NORMALカード非対応化
SYSM_SetBootFlag( BFLG_ILLEGAL_NITRO_CARD );
return FALSE;
}else {
SYSM_SetBootFlag( BFLG_BOOT_DECIDED | BFLG_BOOT_NITRO );
return TRUE;
}
}
#endif
// TPリード可能かどうかを調べる。
BOOL SYSM_IsTPReadable( void )
{
if( SYSM_GetBootFlag() & BFLG_BOOT_DECIDED ) return FALSE;
else return TRUE;
}
// ARM7-ARM9共有リソースのbootFlagへの値のセット
void SYSM_SetBootFlag( u32 value )
{
BOOL preIrq = OS_DisableIrq();
LockVariable *lockp = &GetSYSMWork()->boot_flag;
( void )OS_LockByWord( BOOTFLAG_LOCK_ID, &(lockp->lock), (void (*)( void ))0x00000000);
lockp->value |= value;
( void )OS_UnLockByWord(BOOTFLAG_LOCK_ID, &(lockp->lock), (void (*)( void ))0x00000000);
( void )OS_RestoreIrq( preIrq );
}
void SYSM_ClearBootFlag( u32 value )
{
BOOL preIrq = OS_DisableIrq();
LockVariable *lockp = &GetSYSMWork()->boot_flag;
( void )OS_LockByWord( BOOTFLAG_LOCK_ID, &(lockp->lock), (void (*)( void ))0x00000000);
lockp->value &= ~value;
( void )OS_UnLockByWord(BOOTFLAG_LOCK_ID, &(lockp->lock), (void (*)( void ))0x00000000);
( void )OS_RestoreIrq( preIrq );
}
// ============================================================================
// 割り込み処理
// ============================================================================
// サブプロセッサ割り込み
static void INTR_SubpIRQ( void )
{
OS_SetIrqCheckFlag( OS_IE_SUBP );
}
// ============================================================================
// アプリ起動処理
// ============================================================================
// エントリアドレスの正当性チェック
static void SYSMi_CheckEntryAddress( void )
{
// エントリアドレスがROM内登録エリアかAGBカートリッジエリアなら、無限ループに入る。
if( !( ( (u32)GetRomHeaderAddr()->main_entry_address >= HW_MAIN_MEM )
&& ( (u32)GetRomHeaderAddr()->main_entry_address < SYSM_ARM9_MMEM_ENTRY_ADDR_LIMIT ) )
|| !( ( ( (u32)GetRomHeaderAddr()->sub_entry_address >= HW_MAIN_MEM )
&& ( (u32)GetRomHeaderAddr()->sub_entry_address < SYSM_ARM7_LOAD_MMEM_LAST_ADDR ) )
|| ( ( (u32)GetRomHeaderAddr()->sub_entry_address >= HW_WRAM )
&& ( (u32)GetRomHeaderAddr()->sub_entry_address < SYSM_ARM7_LOAD_WRAM_LAST_ADDR ) ) ) )
{
OS_TPrintf("entry address invalid.\n");
#ifdef __DEBUG_SECURITY_CODE
DispSingleColorScreen( SCREEN_YELLOW );
#endif
while( 1 ) {}
}
OS_TPrintf("entry address valid.\n");
}
// ARM7によるNITROゲームのロード完了を確認する。
static BOOL SYSMi_CheckARM7LoadNITROCard( void )
{
if( SYSMi_ExistCard()
// && !( SYSM_GetBootFlag() & BFLG_LOAD_CARD_COMPLETED )
) {
return FALSE;
}
return TRUE;
}
// SystemMenuで使用したレジスタメモリのクリア
static void SYSMi_MainpRegisterAndRamClear( BOOL isPlatformTWL )
{
// 最後がサブプロセッサ割り込み待ちなので、IMEはクリアしない。
( void )OS_SetIrqMask(0);
( void )OS_ResetRequestIrqMask( (u32)~0 );
// メモリクリア
GX_SetBankForLCDC(GX_VRAM_LCDC_ALL); // VRAM クリア
MI_CpuClearFast((void*)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
( void )GX_DisableBankForLCDC();
// MI_CpuClearFast((void *)HW_ITCM, HW_ITCM_SIZE); // ITCM クリア ※ITCMにはSDKのコードが入っているので、gameBoot.cでクリアする。
// MI_CpuClearFast((void *)HW_DTCM, HW_DTCM_SIZE-0x800); // DTCM クリア ※DTCMはスタック&SDK変数入りなので、最後にgameBoot.cでクリアしている。
MI_CpuClearFast((void *)HW_OAM, HW_OAM_SIZE); // OAM クリア
MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // パレット クリア
MI_CpuClearFast((void *)HW_DB_OAM, HW_DB_OAM_SIZE); // OAM クリア
MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // パレット クリア
// レジスタクリア
MI_CpuClearFast((void*)(HW_REG_BASE + 0x8), 0x12c); // BG0CNT KEYCNT
MI_CpuClearFast((void*)(HW_REG_BASE + 0x280), 0x40); // DIVCNT SQRTD3
MI_CpuClearFast((void*)(HW_REG_BASE + 0x1000), 0x6e); // DISP1CNT1 DISPBRTCNT1
CP_SetDiv32_32( 0, 1 );
reg_PXI_SUBP_FIFO_CNT = 0x4008;
reg_GX_DISPCNT = 0;
reg_GX_DISPSTAT = 0; // ※ reg_GX_VCOUNTはベタクリアできないので、この先頭部分のクリアを分離する。
// NTRの時には、バナーがある時は、MCCNTのカードイネーブルビットが"1"で、無いときには"0"になっていたが、
// NTR起動の時には、ここでもそれを踏襲しないとダメかも。。。
// クリアしていないレジスタは、VCOUNT, PIFCNT, MC-, EXMEMCNT, IME, RBKCNT1, PAUSE, POWLCDCNT, 全3D系です。
if( isPlatformTWL ) {
// TWL専用レジスタのクリア
}
}
// ============================================================================
// サブルーチン
// ============================================================================
// ISデバッガのバナービューモード起動かどうか
BOOL SYSM_IsDebuggerBannerViewMode( void )
{
#ifdef __IS_DEBUGGER_BUILD
return ( GetSYSMWork()->isOnDebugger &&
SYSMi_ExistCard() &&
GetRomHeaderAddr()->dbgRomSize == 0 ) ? TRUE : FALSE;
#else
return FALSE;
#endif // __IS_DEBUGGER_BUILD
}
// NITRO設定データの読み出し。
static void SYSMi_ReadNTRSetting( void )
{
RTCDate date;
RTCTime time;
GetSYSMWork()->ncd_invalid = NVRAMm_ReadNitroConfigData( GetNCDWork() );
// NVRAMからNITRO設定データをロード。
if( GetSYSMWork()->ncd_invalid ) { // リードしたNITRO設定データが無効だったら、0クリアしたものを使用。
OS_TPrintf(" NCD destroyed.\n" );
SVC_CpuClearFast( 0x0000, GetNCDExWork(), sizeof(NitroConfigDataEx) );
GetNCDExWork()->version = NITRO_CONFIG_DATA_EX_VERSION;
GetNCDWork()->option.backLightBrightness= 2; // 出荷時と同じ値に。
GetNCDWork()->option.language = LANG_ENGLISH; // プリセットが必要なデータはプリセットしておく
GetNCDWork()->option.destroyFlashFlag = 1;
GetNCDWork()->owner.birthday.month = 1;
GetNCDWork()->owner.birthday.day = 1;
GetNCDExWork()->valid_language_bitmap = VALID_LANG_BITMAP;
}
// RTCのリセット or おかしい値を検出した場合は初回起動シーケンスへ。
( void )RTC_GetDateTime( &date, &time );
if( !SYSM_CheckRTCDate( &date ) ||
!SYSM_CheckRTCTime( &time )
#ifndef __IS_DEBUGGER_BUILD // 青デバッガではRTCの電池がないので、毎回ここにひっかかって設定データが片方クリアされてしまう。これを防ぐスイッチ。
|| ( GetSYSMWork()->rtcStatus & 0x01 )
#endif
) { // RTCの異常を検出したら、rtc入力フラグrtcOffsetを0にしてNVRAMに書き込み。
OS_TPrintf("\"RTC reset\" or \"Illegal RTC data\" detect!\n");
GetNCDWork()->option.input_rtc = 0;
GetNCDWork()->option.rtcOffset = 0;
GetNCDWork()->option.rtcLastSetYear = 0;
( void )NVRAMm_WriteNitroConfigData( GetNCDWork() );
}
}
// TWL設定データの読み出し
static void SYSMi_ReadTWLSetting( void )
{
}
// NTR設定とTWL設定をベリファイして、不一致があれば、NTR設定を更新
static void SYSMi_VerifyNTRSetting( void )
{
}
// RTCの日付が正しいかチェック
BOOL SYSM_CheckRTCDate( RTCDate *datep )
{
if( ( datep->year >= 100 )
|| ( datep->month < 1 ) || ( datep->month > 12 )
|| ( datep->day < 1 ) || ( datep->day > 31 )
|| ( datep->week >= RTC_WEEK_MAX ) ) {
return FALSE;
}
return TRUE;
}
// RTCの時刻が正しいかチェック
BOOL SYSM_CheckRTCTime( RTCTime *timep )
{
if( ( timep->hour > 23 )
|| ( timep->minute > 59 )
|| ( timep->second > 59 ) ) {
return FALSE;
}
return TRUE;
}
// バナーファイルの読み込みの実体
static void SYSMi_ReadCardBannerFile( void )
{
s32 lockCardID;
BannerFile *pBanner = &s_bannerBuf;
if( ( !SYSMi_ExistCard() ) || ( *(void** )BANNER_ROM_OFFSET == NULL ) ) {
s_isBanner = FALSE;
return;
}
// ROMカードからのバナーデータのリード
if ( ( lockCardID = OS_GetLockID() ) > 0 ) {
( void )OS_LockCard( (u16 )lockCardID );
DC_FlushRange( pBanner, sizeof(BannerFile) );
SYSM_ReadCard(*(void** )BANNER_ROM_OFFSET, pBanner, sizeof(BannerFile) );
( void )OS_UnLockCard( (u16 )lockCardID );
OS_ReleaseLockID( (u16 )lockCardID );
}
// バナーデータの正誤チェック
{
int i;
u16 calc_crc = 0xffff;
u16 *hd_crcp = (u16 *)&pBanner->h.crc16_v1;
BannerCheckParam *chkp = &s_bannerCheckList[ 0 ];
s_isBanner = TRUE;
for( i = 0; i < BNR_VER_MAX; i++ ) {
if( i < pBanner->h.version ) {
calc_crc = SVC_GetCRC16( calc_crc, chkp->srcp, chkp->size );
if( calc_crc != *hd_crcp++ ) {
s_isBanner = FALSE;
break;
}
}else {
MI_CpuClear16( chkp->srcp, chkp->size );
}
chkp++;
}
if( !s_isBanner ) {
MI_CpuClear16( &s_bannerBuf, sizeof(BannerFile) );
}
}
}
// クローンブート判定
static void SYSMi_CheckCardCloneBoot( void )
{
s32 lockCardID;
u8 *buffp = (u8 *)&s_bannerBuf; // バナー用バッファをテンポラリとして使用
u32 total_rom_size = GetRomHeaderAddr()->total_rom_size ? GetRomHeaderAddr()->total_rom_size : 0x01000000;
u32 file_offset = total_rom_size & 0xFFFFFE00;
if( !SYSMi_ExistCard() ) {
return;
}
if ( ( lockCardID = OS_GetLockID() ) > 0 ) {
( void )OS_LockCard( (u16 )lockCardID );
DC_FlushRange( buffp, BNR_IMAGE_SIZE );
SYSM_ReadCard( (void *)file_offset, buffp, BNR_IMAGE_SIZE );
( void )OS_UnLockCard( (u16 )lockCardID );
OS_ReleaseLockID( (u16 )lockCardID );
}
buffp += total_rom_size & 0x000001FF;
if( *buffp++ == 'a' && *buffp == 'c' ) {
GetSYSMWork()->clone_boot_mode = CLONE_BOOT_MODE;
}else {
GetSYSMWork()->clone_boot_mode = OTHER_BOOT_MODE;
}
}
// タッチパネルキャリブレーション
static void SYSMi_CaribrateTP( void )
{
#ifndef __TP_OFF
TPCalibrateParam calibrate;
( void )TP_CalcCalibrateParam(&calibrate, // タッチパネル初期化
GetNCDWork()->tp.raw_x1, GetNCDWork()->tp.raw_y1, (u16)GetNCDWork()->tp.dx1, (u16)GetNCDWork()->tp.dy1,
GetNCDWork()->tp.raw_x2, GetNCDWork()->tp.raw_y2, (u16)GetNCDWork()->tp.dx2, (u16)GetNCDWork()->tp.dy2 );
TP_SetCalibrateParam(&calibrate);
OS_Printf("TP_calib: %4d %4d %4d %4d %4d %4d\n",
GetNCDWork()->tp.raw_x1, GetNCDWork()->tp.raw_y1, (u16)GetNCDWork()->tp.dx1, (u16)GetNCDWork()->tp.dy1,
GetNCDWork()->tp.raw_x2, GetNCDWork()->tp.raw_y2, (u16)GetNCDWork()->tp.dx2, (u16)GetNCDWork()->tp.dy2 );
#endif
}
// RTCクロック補正値をセット
static void SYSMi_WriteAdjustRTC( void )
{
#ifndef __IS_DEBUGGER_BUILD // デバッガ用ビルド時は補正しない。
RTCRawAdjust raw;
raw.adjust = GetNCDWork()->option.rtcClockAdjust; // ncd_invalid時にはrtcClockAdjustは
// 0クリアされているため補正機能は使用されない
( void )RTCi_SetRegAdjust( &raw );
#endif /* __IS_DEBUGGER_BUILD */
}
// FIFO経由でARM7にメッセージ通知。※PXI_FIFO_TAG_USER_1を使用。
static BOOL SYSMi_SendMessageToARM7(u32 msg)
{
#pragma unused(msg)
return TRUE;
}
// NTR,TWLカード存在チェック 「リターン 1カード認識 0カードなし」
static int SYSMi_ExistCard( void )
{
if( ( GetRomHeaderAddr()->nintendo_logo_crc16 == 0xcf56 ) &&
( GetRomHeaderAddr()->header_crc16 == GetSYSMWork()->cardHeaderCrc16) ) {
return TRUE; // NTR,TWLカードありNintendoロゴCRC、カードヘッダCRCが正しい場合
// ※Nintendoロゴデータのチェックは、特許の都合上、ロゴ表示ルーチン起動後に行います。
}else {
return FALSE; // NTR,TWLカードなし
}
}
// Nintendoロゴチェック 「リターン 1:Nintendoロゴ認識成功 0失敗」
BOOL SYSM_CheckNinLogo(u16 *logo_cardp)
{
u16 *logo_orgp = (u16 *)SYSROM9_NINLOGO_ADR; // ARM9のシステムROMのロゴデータとカートリッジ内のものを比較
u16 length = NINTENDO_LOGO_LENGTH >> 1;
while(length--) {
if(*logo_orgp++ != *logo_cardp++) return FALSE;
}
return TRUE;
}
// スリープモードへの遷移
void SYSM_GoSleepMode( void )
{
#ifndef __IS_DEBUGGER_BUILD // デバッガ用ビルド時はスリープしない。
PM_GoSleepMode( (PMWakeUpTrigger)( (PAD_DetectFold() ? PM_TRIGGER_COVER_OPEN : 0) | PM_TRIGGER_RTC_ALARM ),
0,
0 );
#endif /* __IS_DEBUGGER_BUILD */
}
// バックライト輝度調整
void PMm_SetBackLightBrightness( void )
{
( void )PMi_WriteRegister( 4, (u16)NCD_GetBackLightBrightness() );
( void )PM_SetBackLight( PM_LCD_ALL, PM_BACKLIGHT_ON );
}
//======================================================================
// デバッグ関数
//======================================================================
// 初期データのデバッグ表示
#ifdef __SYSM_DEBUG
static void SYSMi_DispInitialDebugData( void )
{
OS_Printf("SYSM version :20%x\n", SYSMENU_VER);
if( GetMovedInfoFromIPL1Addr()->isOnDebugger ) OS_Printf("Run On IS-DEBUGGER\n");
else OS_Printf("Run On IS-EMULATOR\n");
if(GetMovedInfoFromIPL1Addr()->rtcStatus & 0x01) OS_Printf("RTC reset is detected!\n");
if(GetMovedInfoFromIPL1Addr()->rtcError) OS_Printf("RTC error is detected!\n");
#if 0
OS_Printf("NvDate :%4d\n",sizeof(NvDate));
OS_Printf("NvNickname :%4d\n",sizeof(NvNickname));
OS_Printf("NvComment :%4d\n",sizeof(NvComment));
OS_Printf("NvOwnerInfo :%4d\n",sizeof(NvOwnerInfo));
OS_Printf("NvAlarm :%4d\n",sizeof(NvAlarm));
OS_Printf("NvTpCalibData:%4d\n",sizeof(NvTpCalibData));
OS_Printf("NvOption :%4d\n",sizeof(NvOption));
OS_Printf("NCD :%4d\n",sizeof(NitroConfigData));
OS_Printf("NCDStore :%4d\n",sizeof(NCDStore));
#endif
#if 0
{ // ROM_HEADER_BUFFの内容を書き出し
int i,j;
u32 *romhp = (u32 *)GetRomHeaderAddr();
OS_Printf("ROM Header Buff\n ");
for(i = 0; i < 6; i++) {
for(j = 0; j < 4; j++) OS_Printf(" 0x%8x", *romhp++);
OS_Printf("\n ");
}
OS_Printf("\n");
}
{ // ROM_HEADER_BUFFの内容を書き出し
int i,j;
u32 *romhp = (u32 *)MB_CARD_ROM_HEADER_ADDRESS;
OS_Printf("MB Card ROM Header Buff\n ");
for(i = 0; i < 6; i++) {
for(j = 0; j < 4; j++) OS_Printf(" 0x%8x", *romhp++);
OS_Printf("\n ");
}
OS_Printf("\n");
}
#endif /* 0 */
}
#endif /* __SYSM_DEBUG */
#ifdef __DEBUG_SECURITY_CODE
// セキュリティがきちんと働いているかを確認するデバッグコード
static void DispSingleColorScreen( int mode )
{
( void )OS_DisableIrq();
GX_LoadBGPltt ( &security_detection_color[ mode ], 0, sizeof(GXRgb) );
GXS_LoadBGPltt ( &security_detection_color[ mode ], 0, sizeof(GXRgb) );
GX_DispOn();
GXS_DispOn();
GX_SetGraphicsMode ( GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D );
GXS_SetGraphicsMode( GX_BGMODE_0 );
GX_SetMasterBrightness( 0 );
GXS_SetMasterBrightness( 0 );
GX_SetVisiblePlane ( GX_PLANEMASK_NONE );
GXS_SetVisiblePlane( GX_PLANEMASK_NONE );
}
#endif

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: SYSM_util.c
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.h>
#include <sysmenu.h>
// define data------------------------------------------
// extern data------------------------------------------
// function's prototype declaration---------------------
static s64 SYSMi_CalcRtcSecOffset( RTCDate *datep, RTCTime *timep );
// global variable -------------------------------------
// static variable -------------------------------------
// const data -----------------------------------------
// function's description-------------------------------
//======================================================================
// NITRO設定データ ワーク制御
//======================================================================
// NITRO設定データのニックネーム・色・誕生日の初期化。
void NCD_ClearOwnerInfo( void )
{
NitroConfigData *ncdp = GetNCDWork();
MI_CpuClear16( &ncdp->owner, sizeof(NvOwnerInfo) );
ncdp->owner.birthday.month = 1;
ncdp->owner.birthday.day = 1;
ncdp->option.input_birthday = 0;
ncdp->option.input_favoriteColor = 0;
ncdp->option.input_nickname = 0;
}
//======================================================================
// RTCオフセット制御
//======================================================================
// RTCに新しい設定値をセットして、その値をもとにrtcOffset値を算出する。
s64 SYSM_CalcRtcOffsetAndSetDateTime( RTCDate *newDatep, RTCTime *newTimep )
{
RTCDate oldDate;
RTCTime oldTime;
s64 offset0;
s64 offset1;
s64 offset;
// RTCへの新しい値の設定
(void)RTC_GetDateTime( &oldDate, &oldTime ); // ライト直前に現在のRTC値を取得する。
(void)RTC_SetDateTime( newDatep, newTimep ); // 新RTC設定値のセット。
oldTime.second = 0;
// RTC設定時は、今回の設定でどれだけRTC値が変化したか秒オフセット単位を算出。
if( ( oldDate.year < NCD_GetRtcLastSetYear() ) && ( NCD_GetInputRTC() ) ) {
oldDate.year += 100; // 前回の設定今回の設定の間にRTCが一周してしまったら、yearは100を加算してoffsetを計算する。
}
NCD_SetRtcLastSetYear( (u8)newDatep->year );
offset0 = SYSMi_CalcRtcSecOffset( &oldDate, &oldTime ); // 設定直前のRTC値のオフセットを算出
offset1 = SYSMi_CalcRtcSecOffset( newDatep, newTimep ); // 新しくセットされたRTC値のオフセットを算出
offset = NCD_GetRtcOffset() + offset1 - offset0; // 新RTC_ofs と 現在のRTC_ofs の差分の値を加算してリターン。
OS_Printf ("Now Date = year:%3d month:%3d date:%3d hour:%3d minute:%3d second:%3d\n",
oldDate.year, oldDate.month, oldDate.day,
oldTime.hour, oldTime.minute, oldTime.second);
OS_Printf ("Set Date = year:%3d month:%3d date:%3d hour:%3d minute:%3d second:%3d\n",
newDatep->year, newDatep->month, newDatep->day,
newTimep->hour, newTimep->minute, newTimep->second);
OS_Printf ("offset[0] = %x\n", offset0 );
OS_Printf ("offset[1] = %x\n", offset1 );
OS_Printf ("rtcOffset = %x\n", offset );
return offset;
}
// RTCオフセット値の算出
#define SECOND_OFFSET
static s64 SYSMi_CalcRtcSecOffset( RTCDate *datep, RTCTime *timep )
{
u32 i;
int uruu = 0;
int dayNum = 0;
s64 offset;
// 時、分、秒を 秒 or 分オフセットに
#ifdef SECOND_OFFSET
offset = ( timep->hour * 60 + timep->minute ) * 60 + timep->second;
#else
offset = timep->hour * 60 + timep->minute;
#endif
// 月、日を 日数に換算してから、 秒 or 分オフセットに
dayNum = (int)datep->day - 1;
for( i = 1; i < datep->month; i++ ) {
dayNum += SYSM_GetDayNum( datep->year, i );
}
// 年を 日数に換算
if( datep->year > 0 ) {
uruu = ( ( (int)datep->year - 1 ) >> 2 ) + 1; // 指定年-1までのうるう年の個数を算出して、その日数を加算。
}
dayNum += uruu + (u32)( datep->year * 365 );
// 年・月・日を日数に換算した値を 秒 or 分オフセットに
#ifdef SECOND_OFFSET
offset += (s64)( dayNum * 24 * 3600 );
#else
offset += (s64)( dayNum * 24 * 60 );
#endif
return offset;
}
// 指定された年・月の日数を返す。
u32 SYSM_GetDayNum( u32 year, u32 month )
{
u32 dayNum = 31;
if( month == 2 ) {
if( SYSM_IsLeapYear100( year ) ) {
dayNum -= 2;
}else {
dayNum -= 3;
}
}else if( ( month == 4 ) || ( month == 6 ) || ( month == 9 ) || ( month == 11 ) ) {
dayNum--;
}
return dayNum;
}
/*
u32 SYSM_GetDayNum( u32 year, u32 month )
{
u8 date_tbl[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if( ( month == 2 ) && SYSM_IsLeapYear100( year ) ) {
return 29;
}
return date_tbl[ month - 1 ]; // 1月から12月だから1引く
}
*/
// 簡易うるう年の判定 (うるう年1、通常の年0※RTCのとりうる範20002100年に限定する。
BOOL SYSM_IsLeapYear100( u32 year )
{
if( ( year & 0x03 ) || ( year == 100 ) ) { // うるう年は、「4で割り切れ かつ 100で割り切れない年」または「400で割り切れる年」
return FALSE;
}else {
return TRUE;
}
}

View File

@ -0,0 +1,31 @@
#! 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:: 2007-10-03#$
# $Rev: 1319 $
# $Author: kitase_hirotake $
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
#----------------------------------------------------------------------------
SUBDIRS = ARM9
#----------------------------------------------------------------------------
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#===== End of Makefile =====

View File

@ -0,0 +1,70 @@
#----------------------------------------------------------------------------
# Project: TwlSDK - include
# File: ARM9-BB.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 0x02800000
Object $(OBJS_STATIC)
Library $(LLIBS) $(GLIBS) $(CW_LIBS)
}
Overlay bm_mainp
{
After $(TARGET_NAME)
Object $(OBJDIR)/DS_Setting.o $(OBJDIR)/settingMenu.o $(OBJDIR)/rtcSet.o $(OBJDIR)/langSelect.o \
$(OBJDIR)/tpCalib.o $(OBJDIR)/ownerInfo.o $(OBJDIR)/AgbLcdSel.o $(OBJDIR)/autoBoot.o \
$(OBJDIR)/unicode.o $(OBJDIR)/misc.o \
$(OBJDIR)/DS_DownloadPlay.o \
$(OBJDIR)/DS_Chat.o
}
Overlay ipl2_data
{
After bm_mainp
Object ./font/f12han.o
}
Autoload ITCM
{
Address 0x01ff8000
Object * (.itcm)
Object $(OBJS_AUTOLOAD) (.text)
Object $(OBJS_AUTOLOAD) (.rodata)
}
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 ipl2_data
Object * (.ltdmain)
Object $(OBJS_LTDAUTOLOAD)
Library $(LLIBS_EX) $(GLIBS_EX)
}

View File

@ -0,0 +1,81 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - demos - simpleShoot-1
# 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: $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TWL_ARCHGEN = LIMITED
TARGET_BIN = main.srl
LCFILE_SPEC = ARM9-TS.lsf
ROM_SPEC = main.rsf
LOGO_DIR = Logo
SETTING_DIR = DS_Setting
MBOOT_DIR = DS_DownloadPlay
CHAT_DIR = DS_Chat
FONT_DIR = font
FONTS = f12han.dat
FONT_DATAS = $(addprefix $(FONT_DIR)/, $(FONTS))
FONT_OBJS = $(FONT_DATAS:.dat=.o)
SRCS_IPL2 = main.c mainFunc.c launcher.c $(SETTING_DIR)/font.c $(SETTING_DIR)/myChar.c
SRCS_LOGO = logoDemo.c logoData.c
SRCS_SETTING = DS_Setting.c settingMenu.c unicode.c misc.c \
rtcSet.c langSelect.c tpCalib.c ownerInfo.c AgbLcdSel.c autoBoot.c
SRCS_MBOOT = DS_DownloadPlay.c
SRCS_DSCHAT = DS_Chat.c
SRCS = $(SRCS_IPL2) $(addprefix $(LOGO_DIR)/, $(SRCS_LOGO))
SRCS_OVERLAY = $(addprefix $(SETTING_DIR)/,$(SRCS_SETTING)) \
$(addprefix $(MBOOT_DIR)/,$(SRCS_MBOOT)) \
$(addprefix $(CHAT_DIR)/,$(SRCS_DSCHAT)) \
OBJS_OVERLAY += $(FONT_OBJS)
LINCLUDES = $(TWLSDK_ROOT)/build/libraries/spi/arm9/include \
$(TWLSDK_ROOT)/build/libraries/mb/common/include \
$(SRCDIR)/$(LOGO_DIR) \
$(SRCDIR)/$(SETTING_DIR) \
$(SRCDIR)/$(CHAT_DIR) \
$(SRCDIR)/$(MBOOT_DIR) \
LLIBRARY_DIRS =
LLIBRARIES =
LDEPENDS_NEF =
include $(TWLIPL_ROOT)/build/buildtools/commondefs.sysmenu
#----------------------------------------------------------------------------
do-build : $(FONT_OBJS) $(TARGETS)
include $(TWLIPL_ROOT)/build/buildtools/modulerules.sysmenu
#----------------------------------------------------------------------------
CW_ROOT := $(subst $(SPACE),\ ,$(subst \,/,$(CWFOLDER_NITRO)))
$(FONT_DIR)/%.o : $(FONT_DIR)/%.dat
$(CW_ROOT)/ARM_Tools/Command_Line_Tools/BinToElf.exe $< -aligndata 4 -endian little -output $@
#===== End of Makefile =====

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
#define WAVE_VGROUP000 0
#define BANK_VGROUP000 0
#define SEQ_SONG0 0
#define SEQ_DUMMY 0
#define DUMMY 0
extern const u8 _binary_sound_data_sdat[]; // サウンドデータ

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

View File

@ -0,0 +1,147 @@
#----------------------------------------------------------------------------
# Project: TwlSDK - include
# File: ROM-BB.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).FLX.TWL.sbin$(COMPSUFFIX9)"
OverlayDefs "$(MAKEROM_ARM9:r)_defs.FLX.TWL.sbin$(COMPSUFFIX9)"
OverlayTable "$(MAKEROM_ARM9:r)_table.FLX.TWL.sbin$(COMPSUFFIX9)"
Elf "$(MAKEROM_ARM9:r).tef"
}
Arm7
{
Static "$(MAKEROM_ARM7_BASE:r).FLX.TWL.sbin$(COMPSUFFIX7)"
OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.FLX.TWL.sbin$(COMPSUFFIX7)"
OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.FLX.TWL.sbin$(COMPSUFFIX7)"
Elf "$(MAKEROM_ARM7_BASE:r).tef"
}
Arm9.Ltd
{
Static "$(MAKEROM_ARM9:r).LTD.TWL.sbin$(COMPSUFFIX9)"
OverlayDefs "$(MAKEROM_ARM9:r)_defs.LTD.TWL.sbin$(COMPSUFFIX9)"
OverlayTable "$(MAKEROM_ARM9:r)_table.LTD.TWL.sbin$(COMPSUFFIX9)"
}
Arm7.Ltd
{
Static "$(MAKEROM_ARM7_BASE:r).LTD.TWL.sbin$(COMPSUFFIX7)"
OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.LTD.TWL.sbin$(COMPSUFFIX7)"
OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.LTD.TWL.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 128M
#RomSize 256M
#
# 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 ./etc/myGameBanner.bnr
BannerFile $(TWLSDK_ROOT)/include/twl/specfiles/default.bnr
###
### Setting for TWL
###
#
# BANNER FILE:
#
BannerTWLFile $(TWLSDK_ROOT)/include/twl/specfiles/default.bnr
#
# Boot allowed Media: [GameCard/NAND/SDCard/DownloadPlay]
# possible to choose one or more.
#
BootMedia GameCard NAND SDCard DownloadPlay
#
# Certification FILE:
#
Certificate $(TWLSDK_ROOT)/include/twl/specfiles/default_sgn.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 $(MAKEROM_WRAM_MAPPING)
#
# Codec mode:
# don't have to edit
#
CodecMode $(MAKEROM_CODEC_MODE)
###
#### END
}
RomSpec
{
Offset 0x00000000
Segment ALL
HostRoot data
Root /data
File NTR_IPL_font_m.NFTR
}

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: DS_Chat.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Chat.h"
#include "DS_Setting.h"
// define data------------------------------------------
#define RETURN_BUTTON_TOP_X 2
#define RETURN_BUTTON_TOP_Y 21
#define RETURN_BUTTON_BOTTOM_X ( RETURN_BUTTON_TOP_X + 8 )
#define RETURN_BUTTON_BOTTOM_Y ( RETURN_BUTTON_TOP_Y + 2 )
// extern data------------------------------------------
// function's prototype declaration---------------------
static void DS_ChatInit(void);
static int DS_Chat(void);
// global variable -------------------------------------
// static variable -------------------------------------
// const data -----------------------------------------
// ピクトチャットのメインループ
int DS_ChatMain(void)
{
DS_ChatInit();
while(1) {
OS_WaitIrq( 1, OS_IE_V_BLANK );
ReadKeyPad();
if( DS_Chat() ) {
return 0;
}
if ( PAD_DetectFold() == TRUE ) { // スリープモードへの遷移
SYSM_GoSleepMode();
}
}
return 0;
}
//======================================================
// ピクトチャット
//======================================================
// ピクトチャットの初期化
static void DS_ChatInit( void )
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_WHITE );
switch(csrMenu) {
case 0:
PutStringUTF16( 1 * 8, 0 * 8, TXT_COLOR_BLUE, (const u16 *)L"PictoChat");
break;
}
PutStringUTF16( 4 * 8, 8 * 8, TXT_COLOR_BLACK, (const u16 *)L"Under Construction...");
GXS_SetVisiblePlane( GX_PLANEMASK_BG0 );
}
// ピクトチャット(空処理)
static int DS_Chat(void)
{
BOOL tp_cancel = FALSE;
ReadTpData(); // タッチパネル入力の取得
// [RETURN]ボタン押下チェック
if(tpd.disp.touch) {
tp_cancel = InRangeTp( RETURN_BUTTON_TOP_X * 8, RETURN_BUTTON_TOP_Y * 8 - 4,
RETURN_BUTTON_BOTTOM_X * 8, RETURN_BUTTON_BOTTOM_Y * 8 - 4, &tpd.disp );
}
if( ( pad.trg & PAD_BUTTON_B ) || tp_cancel ) {
return 1;
}
return 0;
}

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: DS_Chat.h
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$
*---------------------------------------------------------------------------*/
#ifndef __DS_CHAT_H__
#define __DS_CHAT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
// define data----------------------------------------------------------
int DS_ChatMain( void );
#ifdef __cplusplus
}
#endif
#endif // __DS_CHAT_H__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: DS_DownloadPlay.h
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$
*---------------------------------------------------------------------------*/
#ifndef __DS_DOWNLOAD_PLAY_H__
#define __DS_DOWNLOAD_PLAY_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
// define data----------------------------------------------------------
int DS_DownloadPlayMain( void );
#ifdef __cplusplus
}
#endif
#endif // __DS_DOWNLOAD_PLAY_H__

View File

@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: AgbLcdSel.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Setting.h"
// define data------------------------------------------
#define CANCEL_BUTTON_LT_X 2
#define CANCEL_BUTTON_LT_Y 21
#define CANCEL_BUTTON_RB_X (CANCEL_BUTTON_LT_X+8)
#define CANCEL_BUTTON_RB_Y (CANCEL_BUTTON_LT_Y+2)
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_AgbLcdSelect_init(void);
int SEQ_AgbLcdSelect(void);
// global variable -------------------------------------
// static variable -------------------------------------
static u16 agbLcd = 0;
// const data -----------------------------------------
static const u8 *const str_lcd[] ATTRIBUTE_ALIGN(2) = {
(const u8 *)"TOP LCD",
(const u8 *)"BOTTOM LCD",
};
static const MenuComponent agbLcdSel = {
2,
10,
8,
0,
4,
8,
WHITE,
HIGHLIGHT_Y,
(const u8 **)&str_lcd,
};
//======================================================
// function's description
//======================================================
// AGBモード設定の初期化
void SEQ_AgbLcdSelect_init(void)
{
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
MI_CpuClearFast(bgBakS,sizeof(bgBakS));
ClearAllStringSJIS();
(void)DrawStringSJIS( 1, 0, YELLOW, (const u8 *)"AGB-MODE LCD SELECT");
(void)DrawStringSJIS( CANCEL_BUTTON_LT_X, CANCEL_BUTTON_LT_Y,HIGHLIGHT_C, (const u8 *)" CANCEL ");
if(GetSYSMWork()->ncd_invalid) {
agbLcd = 0;
}else {
agbLcd = GetNCDWork()->option.agbLcd;
if(agbLcd > 1) agbLcd = 1;
}
DrawMenu((u16)agbLcd, &agbLcdSel);
SVC_CpuClear(0x0000, &tpd, sizeof(TpWork), 16);
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
}
// AGBモード設定
int SEQ_AgbLcdSelect(void)
{
BOOL tp_select;
BOOL tp_cancel = FALSE;
ReadTpData(); // タッチパネル入力の取得
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & (PAD_KEY_DOWN | PAD_KEY_UP)){ // カーソルの移動
agbLcd ^= 0x01;
}
tp_select = SelectMenuByTp((u16 *)&agbLcd, &agbLcdSel);
DrawMenu((u16)agbLcd, &agbLcdSel);
// [CANCEL]ボタン押下チェック
if(tpd.disp.touch) {
tp_cancel = InRangeTp(CANCEL_BUTTON_LT_X*8, CANCEL_BUTTON_LT_Y*8-4,
CANCEL_BUTTON_RB_X*8, CANCEL_BUTTON_RB_Y*8-4, &tpd.disp);
}
if((pad.trg & PAD_BUTTON_A) || (tp_select)) { // メニュー項目への分岐
GetSYSMWork()->ncd_invalid = 0;
GetNCDWork()->option.agbLcd = agbLcd;
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData(GetNCDWork());
SEQ_MainMenu_init();
return 0;
}else if((pad.trg & PAD_BUTTON_B) || (tp_cancel)) {
SEQ_MainMenu_init();
return 0;
}
ReadTpData();
return 0;
}

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: DS_Setting.c
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.h>
#include "main.h"
#include "DS_Setting.h"
// define data-----------------------------------------------------------------
// function's prototype--------------------------------------------------------
int DS_SettingMain();
void VBlankIntr_bm(void);
// extern data-----------------------------------------------------------------
// global variable-------------------------------------------------------------
// static variable-------------------------------------------------------------
// const data------------------------------------------------------------------
// ============================================================================
// function's description
// ============================================================================
int DS_SettingMain()
{
(void)OS_DisableIrq();
// GXS_DispOff(); // LCDC OFF
// reg_GX_POWCNT = 0x7fff; // 表示画面を下LCDに切り替え
OS_Printf("ARM9 bootMenu start.\n");
//---- VRAM クリア
// GX_SetBankForLCDC(GX_VRAM_LCDC_ALL); // VRAMクリアのために一時的にLCDCにVRAMを全て割り当てる。
// MI_CpuClearFast((void*)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
// (void)GX_DisableBankForLCDC();
//---- OAMとパレットクリア
// MI_CpuFillFast( (void*)HW_DB_OAM, 192, HW_DB_OAM_SIZE );
// MI_CpuClearFast((void*)HW_DB_PLTT, HW_PLTT_SIZE);
//---- VRAMの割り当て
// GX_SetBankForBG(GX_VRAM_BG_64_E); // VRAM割り当て
// GX_SetBankForOBJ(GX_VRAM_OBJ_32_FG);
//---- グラフィックス表示モードにする
// GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
//---- BG1の設定
// G2_SetBG1Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf000,
// GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01 );
// G2_SetBG1Priority(3); // BGコントロール セット
//---- OBJ,BG1の表示のみON
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
//---- OBJは2Dマップモードで使用
GXS_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
//---- データロード
// MI_CpuCopyFast(myChar, (void *)HW_BG_VRAM, sizeof(myChar)); // BGキャラクタ セット
// MI_CpuCopyFast(myChar, (void *)HW_OBJ_VRAM, sizeof(myChar)); // OBJキャラクタ セット
// MI_CpuCopyFast(myPlttData, (void *)HW_BG_PLTT, sizeof(myPlttData));// BGパレット セット
// MI_CpuCopyFast(myPlttData, (void *)HW_OBJ_PLTT, sizeof(myPlttData));// OBJパレット セット
//---- Vブランク割込切り替え
(void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr_bm);
(void)OS_EnableIrq();
//---- 表示開始
OS_WaitIrq(1, OS_IE_V_BLANK);
// SVC_WaitVBlankIntr();
// GXS_DispOn();
//---- メインループ前処理
SEQ_MainMenu_init();
//================ メインループ
while(1)
{
OS_WaitIrq(1, OS_IE_V_BLANK);
// SVC_WaitVBlankIntr(); // Vブランク割込終了待ち
ReadKeyPad();
mf_KEYPAD_rapid();
(void)nowProcess(); // メインプロセス実行
if (PAD_DetectFold() == TRUE) { // スリープモードへの遷移
SYSM_GoSleepMode();
}
OS_PrintServer(); // ARM7からのプリントデバッグを処理する
}
}
//=============================================================================
// 割り込みルーチン
//=============================================================================
// Vブランク割り込み
void VBlankIntr_bm(void)
{
//---- OAM、BG-VRAMの更新
DC_FlushRange(oamBakS, sizeof(oamBakS));
MI_CpuCopyFast(oamBakS,(void*)HW_DB_OAM, sizeof(oamBakS));
DC_FlushRange(bgBakS, sizeof(bgBakS));
MI_CpuCopyFast(bgBakS, (void*)(HW_DB_BG_VRAM+0xf000), sizeof(bgBakS));
//---- 割り込みチェックフラグ
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
}

View File

@ -0,0 +1,90 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: DS_Setting/DS_Setting.h
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$
*---------------------------------------------------------------------------*/
#ifndef __DS_SETTING_H__
#define __DS_SETTING_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
#include "font.h"
#include "unicode.h"
// define data----------------------------------------------------------
#define TP_CSR_TOUCH_COUNT 2 // TPカーソルのチャタリング吸収のためのカウント値
#define TP_CSR_DETACH_COUNT 2 // TPカーソルを「選択」と判定するTPデタッチからのカウント値
#define HANDLE_MENU 48
#define HANDLE_RTC_VIEW 240
#define HANDLE_OK_BUTTON 255
#define HANDLE_CANCEL_BUTTON 256
// 数値入力インターフェース用ワークvoid InputDecimal()で使用)
typedef struct InputNumParam {
u16 pos_x; // 入力値の表示X位置
u16 pos_y; // 〃     Y位置
int up_count;
int down_count;
int keta_max; // 最大桁
int value_min; // 入力値の最小
int value_max; // 入力値の最大
int y_offset; // タッチパネル入力の基準位置からのYオフセット
}InputNumParam;
// global variable------------------------------------------------------
extern u16 csrMenu;
extern BOOL initialSet;
// function-------------------------------------------------------------
extern int DS_SettingMain( void );
extern void SEQ_MainMenu_init(void);
extern int SEQ_MainMenu(void);
extern void SEQ_Setting_init(void);
extern int SEQ_Setting(void);
extern void SEQ_OwnerInfo_init(void);
extern int SEQ_OwnerInfo(void);
extern void SEQ_RtcSet_init(void);
extern int SEQ_RtcSet(void);
extern void SEQ_LangSelect_init(void);
extern int SEQ_LangSelect(void);
extern void SEQ_TP_Calibration_init(void);
extern int SEQ_TP_Calibration(void);
extern void SEQ_AgbLcdSelect_init(void);
extern int SEQ_AgbLcdSelect(void);
extern void SEQ_AutoBootSelect_init(void);
extern int SEQ_AutoBootSelect(void);
extern void DrawMenu(u16 nowCsr, const MenuComponent *menu);
extern BOOL SelectMenuByTp(u16 *nowCsr, const MenuComponent *menu);
//extern BOOL InRangeTp(u16 lt_x, u16 lt_y, u16 rb_x, u16 rb_y, TPData *tgt);
extern BOOL InRangeTp(int lt_x, int lt_y, int rb_x, int rb_y, TPData *tgt);
extern void DrawOKCancelButton(void);
extern void CheckOKCancelButton(BOOL *tp_ok, BOOL *tp_cancel);
extern void InputDecimal(int *tgtp, InputNumParam *inpp);
extern void ClearRTC( void );
#ifdef __cplusplus
}
#endif
#endif // __DS_SETTING_H__

View File

@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: autoBoot.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Setting.h"
// define data------------------------------------------
#define CANCEL_BUTTON_LT_X 2
#define CANCEL_BUTTON_LT_Y 21
#define CANCEL_BUTTON_RB_X (CANCEL_BUTTON_LT_X+8)
#define CANCEL_BUTTON_RB_Y (CANCEL_BUTTON_LT_Y+2)
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_AutoBootSelect_init(void);
int SEQ_AutoBootSelect(void);
// global variable -------------------------------------
// static variable -------------------------------------
static u16 autoBootFlag = 0;
// const data -----------------------------------------
static const u8 *const str_lcd[] ATTRIBUTE_ALIGN(2) = {
(const u8 *)" OFF ",
(const u8 *)" ON ",
};
static const MenuComponent autoBootSel = {
2,
12,
8,
0,
4,
8,
WHITE,
HIGHLIGHT_Y,
(const u8 **)&str_lcd,
};
//======================================================
// function's description
//======================================================
// AGBモード設定の初期化
void SEQ_AutoBootSelect_init(void)
{
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
MI_CpuClearFast(bgBakS,sizeof(bgBakS));
ClearAllStringSJIS();
(void)DrawStringSJIS( 1, 0, YELLOW, (const u8 *)"AUTO BOOT SELECT");
(void)DrawStringSJIS( CANCEL_BUTTON_LT_X, CANCEL_BUTTON_LT_Y,HIGHLIGHT_C, (const u8 *)" CANCEL ");
if(GetSYSMWork()->ncd_invalid) {
autoBootFlag = 0;
}else {
autoBootFlag = GetNCDWork()->option.autoBootFlag;
if(autoBootFlag > 1) autoBootFlag = 1;
}
DrawMenu((u16)autoBootFlag, &autoBootSel);
SVC_CpuClear(0x0000, &tpd, sizeof(TpWork), 16);
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
}
// AGBモード設定
int SEQ_AutoBootSelect(void)
{
BOOL tp_select;
BOOL tp_cancel = FALSE;
ReadTpData(); // タッチパネル入力の取得
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & (PAD_KEY_DOWN | PAD_KEY_UP)){ // カーソルの移動
autoBootFlag ^= 0x01;
}
tp_select = SelectMenuByTp((u16 *)&autoBootFlag, &autoBootSel);
DrawMenu((u16)autoBootFlag, &autoBootSel);
// [CANCEL]ボタン押下チェック
if(tpd.disp.touch) {
tp_cancel = InRangeTp(CANCEL_BUTTON_LT_X*8, CANCEL_BUTTON_LT_Y*8-4,
CANCEL_BUTTON_RB_X*8, CANCEL_BUTTON_RB_Y*8-4, &tpd.disp);
}
if((pad.trg & PAD_BUTTON_A) || (tp_select)) { // メニュー項目への分岐
GetSYSMWork()->ncd_invalid = 0;
GetNCDWork()->option.autoBootFlag = autoBootFlag;
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData(GetNCDWork());
SEQ_MainMenu_init();
return 0;
}else if((pad.trg & PAD_BUTTON_B) || (tp_cancel)) {
SEQ_MainMenu_init();
return 0;
}
ReadTpData();
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: font.h
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$
*---------------------------------------------------------------------------*/
#ifndef __FONT_H_
#define __FONT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
// define data----------------------------------
#define STR_ENTRY_MAX_NUM 256 // 登録可能な文字列データの最大個数
#define SJIS_CHAR_VRAM_OFFSET 0x4000 // SJIS文字列キャラクタ用VRAMのオフセット値
#define SJIS_CHAR_VRAM_SIZE (0x8000 + 0x20) //             のサイズ0x20はヒープのヘッダ
#define VRAM_M_ARENA_LO (HW_BG_VRAM + SJIS_CHAR_VRAM_OFFSET - 0x20)
#define VRAM_M_ARENA_HI (VRAM_M_ARENA_LO + SJIS_CHAR_VRAM_SIZE)
#define VRAM_S_ARENA_LO (HW_DB_BG_VRAM + SJIS_CHAR_VRAM_OFFSET - 0x20)
#define VRAM_S_ARENA_HI (VRAM_S_ARENA_LO + SJIS_CHAR_VRAM_SIZE)
// VRAMアリーナのLo & Hi
// SJISコード判定用の値
#define SJIS_HIGHER_CODE1_MIN 0x81
#define SJIS_HIGHER_CODE1_MAX 0x9f
#define SJIS_HIGHER_CODE2_MIN 0xe0
#define SJIS_HIGHER_CODE2_MAX 0xea
// 関数のエラーリターン値
#define DSJIS_ERR_ENTRY_GET_FAILED 0x8000
#define DSJIS_ERR_ENTRY_ALLOC_FAILED 0x8001
#define DSJIS_ERR_CHAR_ALLOC_FAILED 0x8002
#define DSJIS_ERR_STR_MEMORY_OVER 0x8003
#define DSJIS_ERR_STR_LENGTH_TOO_LONG 0x8004
// SetTargetScreenSJISの引数target
typedef enum TargetScreen {
TOP_SCREEN =0,
BOTTOM_SCREEN
}TargetScreen;
// フォント種類データSelectFontで指定
typedef enum FontType{ // 全角  半角
FONT12, // 12x12 & 12x 7dot
FONT_TYPE_MAX
}FontType;
// function's prototype declaration-------------
void InitFont( TargetScreen target );
void SetFont( FontType font );
void SetTargetScreenSJIS( TargetScreen target );
u16 ChangeColorSJIS( u16 handle, u16 new_color );
// 以下の表示関数は、データアドレスからデータハンドルを算出するので、ハンドルを引数で与えなくて良いが、同一アドレスのデータを複数場所に配置することができない。
u16 DrawStringSJIS ( int x, int y, u16 color, const void *str );
u16 DrawHexSJIS ( int x, int y, u16 color, const void *hexp, u16 figure );
u16 DrawDecimalSJIS( int x, int y, u16 color, const void *hexp, u16 figure, u16 size );
// Ex系は、引数にindexを設けることで、上記関数で制限されている同一アドレスデータの複数場所配置に対応している。
u16 DrawStringSJISEx ( int x, int y, u16 color, const void *strp, u32 index );
u16 DrawHexSJISEx ( int x, int y, u16 color, const void *hexp, u16 figure, u32 index );
u16 DrawDecimalSJISEx( int x, int y, u16 color, const void *hexp, u16 figure, u16 size, u32 index );
// 表示文字列クリア関数
void ClearStringSJIS( void *datap );
void ClearStringSJISEx( void *datap, u32 handleIndex );
void ClearStringSJIS_handle( u16 handle );
void ClearAllStringSJIS( void );
#ifdef __cplusplus
}
#endif
#endif // __FONT_H_

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: langSelect.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Setting.h"
// define data------------------------------------------
#define CANCEL_BUTTON_LT_X 2
#define CANCEL_BUTTON_LT_Y 21
#define CANCEL_BUTTON_RB_X (CANCEL_BUTTON_LT_X+8)
#define CANCEL_BUTTON_RB_Y (CANCEL_BUTTON_LT_Y+2)
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_LangSelect_init(void);
int SEQ_LangSelect(void);
// global variable -------------------------------------
// static variable -------------------------------------
static NvLangCode langCode; // 言語コード
// const data -----------------------------------------
static const u8 *const str_language[] ATTRIBUTE_ALIGN(2) = {
(const u8 *)"にほんご ",
(const u8 *)"English ",
(const u8 *)"Francais",
(const u8 *)"Deutsch ",
(const u8 *)"Italiano",
(const u8 *)"Espanol ",
};
static const MenuComponent langSel = {
(u16)LANG_CODE_MAX,
10,
5,
0,
2,
8,
WHITE,
HIGHLIGHT_Y,
(const u8 **)&str_language,
};
//======================================================
// function's description
//======================================================
// 言語設定の初期化
void SEQ_LangSelect_init(void)
{
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
MI_CpuClearFast(bgBakS, sizeof(bgBakS));
SVC_CpuClearFast(0xc0, oamBakS, sizeof(oamBakS));
ClearAllStringSJIS();
(void)DrawStringSJIS( 1, 0, YELLOW, (const u8 *)"LANGUAGE SELECT");
(void)DrawStringSJIS( CANCEL_BUTTON_LT_X, CANCEL_BUTTON_LT_Y,HIGHLIGHT_C, (const u8 *)" CANCEL ");
if( initialSet ) {
(void)DrawStringSJIS( 8, 18, RED, (const u8 *)"Select language.");
}
if((GetSYSMWork()->ncd_invalid) || (GetNCDWork()->option.language >= LANG_CODE_MAX)) {
langCode = LANG_ENGLISH;
}else {
langCode = (NvLangCode)GetNCDWork()->option.language;
}
DrawMenu((u16)langCode, &langSel);
SVC_CpuClear(0x0000,&tpd, sizeof(TpWork),16);
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
}
// 言語選択
int SEQ_LangSelect(void)
{
BOOL tp_select,tp_cancel = FALSE;
ReadTpData(); // タッチパネル入力の取得
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & PAD_KEY_DOWN){ // カーソルの移動
if(++langCode == LANG_CODE_MAX) langCode = (NvLangCode)0;
}
if(pad.trg & PAD_KEY_UP){
if(--langCode < 0) langCode = (NvLangCode)(LANG_CODE_MAX-1);
}
tp_select = SelectMenuByTp((u16 *)&langCode, &langSel);
DrawMenu((u16)langCode, &langSel);
// [CANCEL]ボタン押下チェック
if(tpd.disp.touch) {
tp_cancel = InRangeTp(CANCEL_BUTTON_LT_X*8, CANCEL_BUTTON_LT_Y*8-4,
CANCEL_BUTTON_RB_X*8, CANCEL_BUTTON_RB_Y*8-4, &tpd.disp);
}
if((pad.trg & PAD_BUTTON_A) || (tp_select)) { // メニュー項目への分岐
GetSYSMWork()->ncd_invalid = 0;
GetNCDWork()->option.input_language = 1; // 言語入力フラグを立てる
GetNCDWork()->option.language = langCode;
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData (GetNCDWork());
SEQ_MainMenu_init();
return 0;
}else if((pad.trg & PAD_BUTTON_B) || (tp_cancel)) {
SEQ_MainMenu_init();
return 0;
}
ReadTpData();
return 0;
}

View File

@ -0,0 +1,384 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: myFunc.c
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 "misc.h"
// define data----------------------------------
// function's prototype-------------------------
// extern data----------------------------------
//extern u16 bgBakS[32*24]; // BG バックアップ
//extern GXOamAttr oamBakS[128]; // OAM バックアップ
// const data-----------------------------------
//const u16 csr_charList1[] ={0x008c, 0x008c, 0x008c, 0x008c};
//const u8 str_time_period[]={" . ."};
// global variable------------------------------
int (*nowProcess)(void);
//MyTime myTime;
//KeyWork pad;
// static variable------------------------------
static u16 key_rapid[4];
//static u16 csr_animeCount, csr_animeCharNum;
//static u16 csr_pos_x, csr_pos_y, csr_add_y;
//static u16 blinkCount;
// ============================================================================
// function's description
// ============================================================================
// BgBakオフセット値算出
__inline static u16 *calcBgOffset(u16 pos_x,u16 pos_y)
{
return bgBakS+pos_x+(pos_y<<5);
}
// メインメモリからでも大丈夫な形式での1byteのデータ読み出し。
__inline static u16 ReadByteHWBus(const void *srcp)
{
if( (u32)srcp & 0x00000001 ) return (u16)(*(u16 *)( (u32)srcp ^ 0x00000001 ) >> 8 );
else return (u16)(*(u16 *)( srcp ) & 0x00ff );
}
// 初期化
void mf_init(void)
{
mf_KEYPAD_initRapid();
// mf_BLINK_initCounter();
}
/*
// キー入力読み出し
void mf_KEYPAD_read(void)
{
u16 ReadData= PAD_Read();
pad.trg = (u16)(ReadData & (ReadData ^ pad.cont)); // トリガ 入力
pad.cont= ReadData; // ベタ 入力
}
*/
// キー連射入力処理 初期化(十字キーのみ)
void mf_KEYPAD_initRapid(void)
{
u16 *krp=key_rapid;
*krp++=0;
*krp++=0;
*krp++=0;
*krp++=0;
}
// キー連射入力(十字キーのみ)
void mf_KEYPAD_rapid(void)
{
u16 mask,i;
for(i=0;i<4;i++){
mask=(u16)(0x0001<<(i+4));
if(pad.cont & mask){
key_rapid[i]++;
if(key_rapid[i]==30) {
pad.trg|=mask;
key_rapid[i]=20;
}
}else{
key_rapid[i]=0;
}
}
}
// Xframeウェイト
void mf_waitXframe(u16 frame)
{
BOOL prelIRQ=OS_EnableIrq();
while(frame--) OS_WaitIrq(1, OS_IE_V_BLANK);
(void)OS_RestoreIrq(prelIRQ);
}
// 矩形BGクリア
void mf_clearRect(u16 pos_x,u16 pos_y,u8 height,u8 width)
{
u16 i,j;
u16 *dstp=calcBgOffset(pos_x,pos_y);
for(i=0;i<height;i++) {
for(j=0;j<width;j++) *dstp++=0x0020;
dstp+=0x20-width;
}
}
/*
// 10進データ表示
void mf_drawDecimal(u16 pos_x,u16 pos_y,u16 color,const void *valuep,u8 drawLength,u8 size)
{
u16 count,charCode;
u16 *dstp;
u32 mask,divisor,target;
mask=0xff;
while(--size>0) mask=(mask<<8)|0xff;
target=(*(u32 *)valuep)&mask;
count=10;
divisor=1000000000;
dstp=calcBgOffset(pos_x,pos_y);
while(count) {
CP_SetDiv32_32(target, divisor);
if (count<=drawLength) {
charCode=(u16)(CP_GetDivResult32()+0x0030);
*dstp++ =(u16)(charCode | color);
}
target=(u32)CP_GetDivRemainder32();
CP_SetDiv32_32(divisor, 10);
divisor=(u32)CP_GetDivResult32();
count--;
}
}
// 16進データ表示
void mf_drawHex(u16 pos_x,u16 pos_y,u16 color,const void *valuep,u8 drawLength)
{
u16 count,charCode;
u16 *dstp=calcBgOffset(pos_x,pos_y)+drawLength-1;
for(count=0;count<drawLength;count++){
charCode=ReadByteHWBus(valuep);
if (count & 0x01){
charCode=(u16)((charCode>>4) & 0x000f);
((u8 *)valuep)++;
}else{
charCode=(u16)( charCode & 0x000f);
}
if (charCode<0x000a) charCode+=0x0030;
else charCode+=0x0041-0x000a;
*dstp--=(u16)(charCode | color);
}
}
// 1byte文字列データ表示0x000xffまでの1文字が1byteで良い文字列を描画する
void mf_drawString(u16 pos_x,u16 pos_y, u16 color, const u8 *strp)
{
u16 data16;
u16 *dstp=calcBgOffset(pos_x,pos_y);
while(1) {
data16=ReadByteHWBus(strp++);
if(data16==0) break;
*dstp++=(u16)(color | data16);
}
}
// 2byte文字列データ表示0x0100以降の1文字に2byte必要な文字列を描画する
void mf_drawString2(u16 pos_x,u16 pos_y, u16 color, const u16 *strp)
{
u16 *dstp=calcBgOffset(pos_x,pos_y);
while(*strp) *dstp++ = (u16)(*strp++ | color);
}
// 矩形フレーム描画
void mf_drawRectFrame(u16 pos_x,u16 pos_y,u16 color,u8 height,u8 width)
{
u16 i,j,code;
u16 *dstp;
for(i=0;i<height;i++) {
dstp=calcBgOffset(pos_x,pos_y);
dstp+=(i<<5);
if(i==0){
code=0x0132;
}else if(i==height-1){
code=0x0136;
}else{
code=0x0135;
}
*dstp++=(u16)(color | code);
if((i==0)||(i==height-1)){
for(j=1;j<width-1;j++) *dstp++=(u16)(color | 0x0133);
}else{
dstp+=width-2;
}
*dstp++=(u16)(color | code | 0x0400); // BG_SC_H_FLIP
}
}
// カーソル初期化
void mf_CSR_init(u16 pos_x,u16 pos_y,u16 add_y)
{
csr_pos_x=pos_x;
csr_pos_y=pos_y;
csr_add_y=add_y;
}
// カーソル移動&アニメーション
void mf_CSR_moveAndAnime(int nowNum)
{
u16 *oamp=(u16 *)&oamBakS[0];
// move
oamp[0]=(u16)(csr_pos_y + nowNum*csr_add_y);
oamp[1]=csr_pos_x;
// anime
mf_CSR_anime(csr_charList1);
}
// カーソルアニメーション
void mf_CSR_anime(const u16 *csr_charListp)
{
u16 *oamp=(u16 *)&oamBakS[0];
// anime
if((++csr_animeCount & 0x0f)==0) {
csr_animeCharNum=(u16)((csr_animeCharNum+1) & 0x03);
}
oamp[2]=(u16)(RED | csr_charListp[csr_animeCharNum]);
}
// メッセージ点滅カウンター 初期化
void mf_BLINK_initCounter(void)
{
blinkCount=0;
mf_clearRect(0,20,1,0x0020);
}
// 文字列点滅表示
void mf_BLINK_drawString(u16 pos_x, u16 pos_y, u16 color, const u8 *strp)
{
u16 len=0;
blinkCount++;
if((blinkCount & 0x60)==0x60) {
while(*strp++) len++;
mf_clearRect(pos_x,pos_y,1,(u8)len);
}else {
mf_drawString(pos_x,pos_y,color,strp);
}
}
// 時間表示
void mf_TIME_init(void)
{
BOOL prelIRQ=OS_EnableIrq();
myTime.frame=0;
myTime.hour=0;
myTime.minute=0;
myTime.second=0;
myTime.enable=0;
(void)OS_RestoreIrq(prelIRQ);
}
void mf_TIME_start(int init_flag)
{
if(init_flag) mf_TIME_init();
myTime.enable=1;
}
void mf_TIME_stop(void)
{
myTime.enable=2;
}
void mf_TIME_count(void)
{
if(myTime.enable!=1) return;
myTime.frame++;
if(myTime.frame==60) {
myTime.frame=0;
myTime.second++;
if(myTime.second==60) {
myTime.second=0;
myTime.minute++;
if(myTime.minute==60) {
myTime.minute=0;
myTime.hour++;
}
}
}
}
void mf_TIME_draw(u16 pos_x, u16 pos_y, u16 color)
{
u8 keta;
if(myTime.enable==0) {
return;
}else if(myTime.enable==2){
color=RED;
}
mf_drawString(pos_x,pos_y,color,str_time_period);
if(myTime.hour<10){
keta=1;
}else if(myTime.hour<100){
keta=2;
}else if(myTime.hour<1000){
keta=3;
}else{
keta=4;
}
mf_drawUInt((u16)(pos_x+4-keta), pos_y, color, &myTime.hour,keta,2);
mf_drawUInt((u16)(pos_x+5), pos_y, color, &myTime.minute,2,1);
mf_drawUInt((u16)(pos_x+8), pos_y, color, &myTime.second,2,1);
}
// 文字列コピー
void mf_strcpy(const u8 *str1p,u8 *str2p)
{
while(*str1p) *str2p++=*str1p++;
*str2p=0x00;
}
// 文字列比較
u8 mf_strcmp(const u8 *str1p,const u8 *str2p)
{
while(*str1p) {
if(*str1p++!=*str2p++) return 1;
}
return 0;
}
*/

View File

@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: misc.h
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$
*---------------------------------------------------------------------------*/
#ifndef __MISC_H__
#define __MISC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
#include "main.h"
// define data ---------------------------------
// パレットカラー
#define WHITE (0<<12)
#define RED (1<<12)
#define GREEN (2<<12)
#define BLUE (3<<12)
#define YELLOW (4<<12)
#define CYAN (5<<12)
#define PURPLE (6<<12)
#define LIGHTGREEN (7<<12)
#define HIGHLIGHT_Y (8<<12)
#define HIGHLIGHT_C (9<<12)
#define HIGHLIGHT_W (10<<12)
#define HIGHLIGHT_B (11<<12)
// 時間計測構造体
typedef struct {
int enable;
int frame;
int second;
int minute;
int hour;
}MyTime;
// キーデータ・ワークエリア構造体
//typedef struct {
// u16 trg; // トリガ入力
// u16 cont; // ベタ 入力
//}KeyWork;
// global variable------------------------------
extern MyTime myTime;
//extern KeyWork pad;
extern int (*nowProcess)(void);
// const data-----------------------------------
extern const u16 myPlttData[12][16]; // パレットデータ
extern const u16 myChar[0x2800*8/16]; // キャラクターデータ
// function-------------------------------------
extern void mf_init(void);
extern void mf_KEYPAD_read(void);
extern void mf_KEYPAD_initRapid(void);
extern void mf_KEYPAD_rapid(void);
extern void mf_waitXframe(u16 frame);
extern void mf_clearRect(u16 pos_x,u16 pos_y,u8 height,u8 width);
/*
extern void mf_drawUInt(u16 pos_x,u16 pos_y,u16 color,const void *valuep,u8 drawLength,u8 size);
extern void mf_drawHex(u16 pos_x,u16 pos_y,u16 color,const void *valuep,u8 drawLength);
extern void mf_drawString(u16 pos_x,u16 pos_y,u16 color,const u8 *strp);
extern void mf_drawString2(u16 pos_x,u16 pos_y,u16 color,const u16 *strp);
extern void mf_drawRectFrame(u16 pos_x,u16 pos_y,u16 color,u8 height,u8 width);
extern void mf_CSR_init(u16 pos_x,u16 pos_y,u16 add_y);
extern void mf_CSR_moveAndAnime(int nowNum);
extern void mf_CSR_anime(const u16 *csr_charListp);
extern void mf_BLINK_initCounter(void);
extern void mf_BLINK_drawString(u16 pos_x,u16 pos_y,u16 color,const u8 *strp);
extern void mf_TIME_init(void);
extern void mf_TIME_start(int init_flag);
extern void mf_TIME_stop(void);
extern void mf_TIME_count(void);
extern void mf_TIME_draw(u16 pos_x,u16 pos_y,u16 color);
extern void mf_strcpy(const u8 *str1p,u8 *str2p);
extern u8 mf_strcmp(const u8 *str1p,const u8 *str2p);
*/
#ifdef __cplusplus
}
#endif
#endif // __MISC_H__

View File

@ -0,0 +1,684 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: myChar.c
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 "misc.h"
#include "myFontequ.h"
// パレットデータ--------------------------------------------------------------
#define RGB555(r,g,b) (b<<10|g<<5|r)
// 背景黒ベース
const u16 myPlttData[12][16] = {
{RGB555(31,31,31), RGB555( 0, 0, 0), RGB555(15,15,15), RGB555(31,31,31),}, // White
{RGB555(31,31,31), RGB555(31, 0, 0), RGB555(31,31,31), RGB555(31,31,31),}, // Red
{RGB555(31,31,31), RGB555( 0, 19, 0), RGB555(31,31,31), RGB555(31,31,31),}, // Green
{RGB555(31,31,31), RGB555( 0, 11, 31), RGB555(31,31,31), RGB555(31,31,31),}, // Blue
{RGB555(31,31,31), RGB555(31, 31, 0), RGB555(31,31,31), RGB555(31,31,31),}, // Yellow
{RGB555(31,31,31), RGB555( 0, 31, 31), RGB555(31,31,31), RGB555(31,31,31),}, // Cyan
{RGB555(31,31,31), RGB555(31, 0, 31), RGB555(31,31,31), RGB555(31,31,31),}, // Purple
{RGB555(31,31,31), RGB555( 0, 31, 0), RGB555(31,31,31), RGB555(31,31,31),}, // Light Green
{RGB555(31,31,31), RGB555(31,31,31), RGB555(31, 31, 0), RGB555(31, 31, 0),}, // HighLight Yellow
{RGB555(31,31,31), RGB555(31,31,31), RGB555( 0, 31, 31), RGB555( 0, 31, 31),}, // HighLight CYAN
{RGB555(31,31,31), RGB555(31,31,31), RGB555(31, 31, 31), RGB555(31, 31, 31),}, // HighLight WHITE
{RGB555(31,31,31), RGB555(31,31,31), RGB555( 0, 11, 31), RGB555( 0, 11, 31),}, // HighLight BLUE
};
// キャラクタデータ------------------------------------------------------------
/*
const u16 myChar[0x2800*8/16]={
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //0
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //2
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //3
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //4
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //5
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //6
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //7
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //8
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //a
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //b
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //c
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //d
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //e
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //f
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //10
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //11
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //12
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //13
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //14
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //15
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //16
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //17
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //18
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //19
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1a
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1b
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1c
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1d
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1e
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //1f
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //20
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x1333,0x3321, //21
0x1333,0x3321,0x2333,0x3332,0x1333,0x3321,0x2333,0x3332,
0x2113,0x3211,0x2113,0x3211,0x2123,0x3212,0x3213,0x3321, //22
0x3323,0x3332,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x2133,0x3321,0x1113,0x3211,0x2123,0x3321, //23
0x2133,0x3321,0x1113,0x3211,0x2123,0x3321,0x3233,0x3332,
0x3333,0x3333,0x1333,0x3332,0x1133,0x3211,0x1213,0x3322, //24
0x1123,0x3311,0x1233,0x2112,0x1113,0x3211,0x1223,0x3322,
0x3333,0x3333,0x2133,0x2133,0x1213,0x3212,0x2123,0x3321, //25
0x1233,0x3212,0x2133,0x2121,0x3213,0x3212,0x3323,0x3323,
0x3333,0x3333,0x1133,0x3331,0x2113,0x3212,0x1123,0x3321, //26
0x2113,0x2111,0x3213,0x3213,0x1123,0x2121,0x2233,0x3232,
0x1133,0x3332,0x1133,0x3332,0x1233,0x3332,0x2133,0x3333, //27
0x3233,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3213,0x3333,0x3321,0x1333,0x3332, //28
0x1333,0x3332,0x1333,0x3332,0x2333,0x3331,0x3333,0x3312,
0x3333,0x3333,0x3133,0x3333,0x1233,0x3333,0x2333,0x3321, //29
0x3333,0x3321,0x3333,0x3321,0x1333,0x3332,0x2133,0x3333,
0x3333,0x3333,0x1333,0x3332,0x1213,0x3212,0x1133,0x3321, //2a
0x1233,0x3332,0x1133,0x3321,0x1213,0x3212,0x1323,0x3222,
0x3333,0x3333,0x3333,0x3333,0x1333,0x3332,0x1333,0x3332, //2b
0x1113,0x3211,0x1223,0x3222,0x1333,0x3332,0x2333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //2c
0x1133,0x3332,0x1133,0x3332,0x1233,0x3332,0x2133,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //2d
0x1113,0x3211,0x2223,0x3222,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //2e
0x3333,0x3333,0x3333,0x3333,0x2133,0x3333,0x2233,0x3333,
0x3333,0x3333,0x3333,0x2133,0x3333,0x3213,0x3333,0x3321, //2f
0x1333,0x3332,0x2133,0x3333,0x3213,0x3333,0x3323,0x3333,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //30
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1333,0x3321,0x1133,0x3321,0x1233,0x3321, //31
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x1113,0x3211,0x2223,0x2112,0x1133,0x3211, //32
0x2113,0x3322,0x2113,0x3333,0x1113,0x2111,0x2223,0x3222,
0x3333,0x3333,0x1113,0x3211,0x2223,0x2112,0x1133,0x3211, //33
0x2233,0x2112,0x3333,0x2113,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x3333,0x3211,0x1333,0x3211,0x2133,0x3211, //34
0x3213,0x3211,0x1113,0x2111,0x2223,0x3211,0x3333,0x3322,
0x3333,0x3333,0x1113,0x3211,0x2213,0x3322,0x1113,0x3211, //35
0x2223,0x2112,0x3333,0x2113,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x1133,0x3211,0x2113,0x3322,0x1113,0x3211, //36
0x2113,0x2112,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1113,0x2111,0x2223,0x2122,0x3333,0x3213, //37
0x3333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3332,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x1123,0x3211, //38
0x2113,0x2112,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //39
0x1123,0x2111,0x2233,0x2112,0x1133,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322, //3a
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322, //3b
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x2333,0x3321,
0x3333,0x3333,0x3333,0x3321,0x1333,0x3332,0x2133,0x3333, //3c
0x2133,0x3333,0x1233,0x3333,0x2333,0x3321,0x3333,0x3322,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1133,0x3211, //3d
0x2233,0x3222,0x1133,0x3211,0x2233,0x3222,0x3333,0x3333,
0x3333,0x3333,0x1333,0x3333,0x2333,0x3331,0x3333,0x3212, //3e
0x3333,0x3213,0x3333,0x3321,0x1333,0x3332,0x2333,0x3333,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //3f
0x3223,0x3211,0x1333,0x3321,0x2333,0x3332,0x1333,0x3321,
0x3333,0x3333,0x1133,0x3321,0x2213,0x3212,0x1213,0x2121, //40
0x2113,0x2121,0x2113,0x2121,0x1213,0x3211,0x1123,0x2121,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //41
0x1113,0x2111,0x2113,0x2112,0x2113,0x2113,0x2223,0x2223,
0x3333,0x3333,0x1113,0x3211,0x2113,0x2112,0x1113,0x3211, //42
0x2113,0x2112,0x2113,0x2113,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2223, //43
0x2113,0x3333,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1113,0x3211,0x2113,0x2112,0x2113,0x2113, //44
0x2113,0x2113,0x2113,0x2113,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x1113,0x2111,0x2113,0x2222,0x1113,0x3211, //45
0x2113,0x3222,0x2113,0x3333,0x1113,0x2111,0x2223,0x2222,
0x3333,0x3333,0x1113,0x2111,0x2113,0x2222,0x1113,0x3211, //46
0x2113,0x3222,0x2113,0x3333,0x2113,0x3333,0x2223,0x3333,
0x3333,0x3333,0x1133,0x3211,0x2113,0x3322,0x2113,0x2111, //47
0x2113,0x2112,0x2113,0x2113,0x1123,0x2111,0x2233,0x3222,
0x3333,0x3333,0x2113,0x2113,0x2113,0x2113,0x1113,0x2111, //48
0x2113,0x2112,0x2113,0x2113,0x2113,0x2113,0x2223,0x2223,
0x3333,0x3333,0x1333,0x3321,0x1333,0x3321,0x1333,0x3321, //49
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x3333,0x2113,0x3333,0x2113,0x3333,0x2113, //4a
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x2113,0x2113,0x2113,0x3211,0x1113,0x3322, //4b
0x1113,0x3331,0x2113,0x3311,0x2113,0x2112,0x2223,0x2223,
0x3333,0x3333,0x2113,0x3333,0x2113,0x3333,0x2113,0x3333, //4c
0x2113,0x3333,0x2113,0x3333,0x1113,0x2111,0x2223,0x2222,
0x3333,0x3333,0x2133,0x2133,0x1113,0x1112,0x1113,0x1112, //4d
0x1113,0x1111,0x2113,0x1121,0x2113,0x1121,0x3223,0x2232,
0x3333,0x3333,0x2113,0x2113,0x1113,0x2112,0x1113,0x2112, //4e
0x2113,0x2111,0x2113,0x2111,0x2113,0x2112,0x2223,0x2223,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //4f
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x1113,0x3211,0x2113,0x2112,0x1113,0x3211, //50
0x2113,0x3322,0x2113,0x3333,0x2113,0x3333,0x2223,0x3333,
0x3333,0x3333,0x1133,0x3211,0x2113,0x2112,0x2113,0x2113, //51
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x2111,
0x3333,0x3333,0x1113,0x3211,0x2113,0x2112,0x1113,0x3211, //52
0x2113,0x2112,0x2113,0x2113,0x2113,0x2113,0x2223,0x2223,
0x3333,0x3333,0x1133,0x2111,0x2113,0x3222,0x1123,0x3331, //53
0x1233,0x3311,0x2333,0x2112,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x1113,0x2111,0x1223,0x3221,0x1333,0x3321, //54
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x2113,0x2113,0x2113,0x2113,0x2113,0x2113, //55
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x2113,0x2113,0x2113,0x2113,0x2113,0x2113, //56
0x2113,0x2113,0x2123,0x3213,0x1233,0x3321,0x2333,0x3332,
0x3333,0x3333,0x2113,0x1121,0x2113,0x1121,0x2113,0x1121, //57
0x1113,0x1111,0x1123,0x2112,0x2133,0x2133,0x3233,0x3233,
0x3333,0x3333,0x2113,0x2113,0x2113,0x2113,0x1123,0x3211, //58
0x1233,0x3211,0x2113,0x2112,0x2113,0x2113,0x3223,0x3223,
0x3333,0x3333,0x2113,0x2113,0x2113,0x2113,0x2133,0x3213, //59
0x1133,0x3211,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x1113,0x2111,0x2223,0x2112,0x1333,0x3221, //5a
0x1133,0x3332,0x2113,0x3333,0x1113,0x2111,0x2223,0x2222,
0x3333,0x3333,0x1333,0x3321,0x1333,0x3322,0x1333,0x3332, //5b
0x1333,0x3332,0x1333,0x3332,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x3313,0x3333,0x3123,0x3333,0x1233,0x3333, //5c
0x2333,0x3331,0x3333,0x3312,0x3333,0x3123,0x3333,0x3233,
0x3333,0x3333,0x1333,0x3321,0x2333,0x3321,0x3333,0x3321, //5d
0x3333,0x3321,0x3333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x1333,0x3332,0x2133,0x3321,0x3233,0x3322, //5e
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //5f
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x2222,
0x1333,0x3321,0x1333,0x3321,0x1333,0x3332,0x2333,0x3321, //60
0x3333,0x3332,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2213,0x2112, //61
0x1123,0x2111,0x2113,0x2112,0x1123,0x2111,0x2233,0x2222,
0x2113,0x3333,0x2113,0x3333,0x1113,0x3211,0x2113,0x2112, //62
0x2113,0x2113,0x2113,0x2113,0x1113,0x3211,0x2223,0x3322,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2113,0x2122, //63
0x2113,0x3233,0x2113,0x2133,0x1123,0x3211,0x2233,0x3322,
0x3333,0x2113,0x3333,0x2113,0x1133,0x2111,0x2113,0x2112, //64
0x2113,0x2113,0x2113,0x2113,0x1123,0x2111,0x2233,0x2222,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2113,0x2112, //65
0x1113,0x2111,0x2113,0x3222,0x1123,0x2111,0x2233,0x3222,
0x1333,0x3211,0x1133,0x3322,0x1113,0x3321,0x1123,0x3332, //66
0x1133,0x3332,0x1133,0x3332,0x1133,0x3332,0x2233,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1133,0x2111,0x2113,0x2112, //67
0x2113,0x2113,0x1123,0x2111,0x2213,0x2112,0x1133,0x3211,
0x2113,0x3333,0x2113,0x3333,0x1113,0x3311,0x2113,0x2112, //68
0x2113,0x2113,0x2113,0x2113,0x2113,0x2113,0x2223,0x2223,
0x1333,0x3321,0x2333,0x3332,0x1333,0x3321,0x1333,0x3321, //69
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3211,0x3333,0x3322,0x3333,0x3211,0x3333,0x3211, //6a
0x3333,0x3211,0x3333,0x3211,0x3213,0x3211,0x1123,0x3321,
0x2113,0x3333,0x2113,0x3213,0x2113,0x3211,0x1113,0x3321, //6b
0x1113,0x3321,0x2113,0x3311,0x2113,0x2112,0x2223,0x3223,
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x1333,0x3321, //6c
0x1333,0x3321,0x1333,0x3321,0x1333,0x3321,0x2333,0x3322,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x1211,0x1121, //6d
0x1211,0x1121,0x1211,0x1121,0x1211,0x1121,0x2322,0x2232,
0x3333,0x3333,0x3333,0x3333,0x1113,0x3211,0x2113,0x2112, //6e
0x2113,0x2113,0x2113,0x2113,0x2113,0x2113,0x2223,0x2223,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2113,0x2112, //6f
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x3333,0x3333,0x1113,0x3211,0x2113,0x2112, //70
0x2113,0x2113,0x1113,0x3211,0x2113,0x3322,0x2113,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1133,0x2111,0x2113,0x2112, //71
0x2113,0x2113,0x1123,0x2111,0x2233,0x2112,0x3333,0x2113,
0x3333,0x3333,0x3333,0x3333,0x1133,0x2112,0x1133,0x2111, //72
0x1133,0x3222,0x1133,0x3332,0x1133,0x3332,0x2233,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x1113,0x3322, //73
0x1133,0x3211,0x2233,0x2111,0x1133,0x3211,0x2233,0x3322,
0x1133,0x3332,0x1113,0x3321,0x1123,0x3332,0x1133,0x3332, //74
0x1133,0x3332,0x1133,0x3332,0x1233,0x3321,0x2333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x2113,0x2113,0x2113,0x2113, //75
0x2113,0x2113,0x2113,0x2113,0x1123,0x3211,0x2233,0x3322,
0x3333,0x3333,0x3333,0x3333,0x2113,0x2113,0x2113,0x2113, //76
0x2113,0x2113,0x2113,0x3213,0x1113,0x3321,0x2223,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1211,0x1121,0x1211,0x1121, //77
0x1211,0x1121,0x1211,0x1121,0x1111,0x2111,0x2222,0x3222,
0x3333,0x3333,0x3333,0x3333,0x2113,0x2113,0x2113,0x2113, //78
0x1123,0x3211,0x2113,0x2112,0x2113,0x2113,0x3223,0x3223,
0x3333,0x3333,0x3333,0x3333,0x2113,0x2113,0x2113,0x2113, //79
0x2113,0x2113,0x1123,0x2111,0x2233,0x2112,0x1133,0x3211,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x3211, //7a
0x1333,0x3321,0x1133,0x3332,0x1113,0x2111,0x2223,0x2222,
0x3333,0x3333,0x3333,0x3321,0x1333,0x3332,0x1333,0x3332, //7b
0x2133,0x3333,0x1333,0x3332,0x1333,0x3332,0x3333,0x3321,
0x3333,0x3333,0x1333,0x3332,0x1333,0x3332,0x1333,0x3332, //7c
0x1333,0x3332,0x1333,0x3332,0x1333,0x3332,0x2333,0x3332,
0x3333,0x3333,0x1333,0x3332,0x3333,0x3321,0x3333,0x3321, //7d
0x3333,0x3213,0x3333,0x3321,0x3333,0x3321,0x1333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3113,0x3333, //7e
0x1221,0x2133,0x2332,0x3211,0x3333,0x3322,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //7f
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x2211,0x2222,0x2211,0x2222,0x2211,0x2222,0x2211,0x2222, //80
0x2211,0x2222,0x2211,0x2222,0x2211,0x2222,0x2211,0x2222,
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222, //81
0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,0x1111,0x2222,
0x1111,0x2211,0x1111,0x2211,0x1111,0x2211,0x1111,0x2211, //82
0x1111,0x2211,0x1111,0x2211,0x1111,0x2211,0x1111,0x2211,
0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111, //83
0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,0x1111,
0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x2222, //84
0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,
0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,0x1333,0x3331, //85
0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,
0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,0x1333,0x3331, //86
0x1111,0x1111,0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //87
0x1111,0x1111,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x1113,0x3333,0x2213, //88
0x3333,0x1213,0x3333,0x1213,0x3333,0x1213,0x3333,0x1213,
0x3333,0x3333,0x3333,0x3333,0x1111,0x1111,0x2222,0x2222, //89
0x1111,0x1111,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1111,0x1111,0x2222,0x2222, //8a
0x1111,0x1111,0x1333,0x3331,0x1333,0x3331,0x1333,0x3331,
0x3333,0x1213,0x3333,0x1213,0x3333,0x1213,0x3333,0x1213, //8b
0x3333,0x1213,0x3333,0x1213,0x3333,0x1213,0x3333,0x1213,
0x3133,0x3333,0x1133,0x3333,0x1133,0x3331,0x1133,0x3311, //8c
0x1133,0x3321,0x1133,0x3332,0x2133,0x3333,0x3233,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1113,0x3332, //8d
0x2123,0x3213,0x1133,0x3321,0x1213,0x3212,0x2113,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //8e
0x3333,0x3321,0x3213,0x3213,0x3213,0x3213,0x2133,0x3323,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1333,0x3332, //8f
0x1133,0x3332,0x2213,0x3321,0x3323,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x2133,0x3333, //90
0x1113,0x3321,0x1223,0x3332,0x2133,0x3333,0x1213,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1113,0x3312, //91
0x2123,0x3323,0x1113,0x3321,0x2113,0x3213,0x2113,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3213,0x3321, //92
0x1123,0x3211,0x2113,0x3212,0x1223,0x3322,0x1333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1333,0x3332, //93
0x1213,0x3321,0x1113,0x3212,0x1213,0x3211,0x1323,0x3322,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1333,0x3332, //94
0x1333,0x3321,0x1133,0x3332,0x1213,0x3321,0x1123,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //95
0x1333,0x3321,0x2113,0x3212,0x3223,0x3213,0x1333,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //96
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //97
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //98
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //99
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9a
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9b
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9c
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9d
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9e
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //9f
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //a0
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //a1
0x3333,0x3333,0x1133,0x3321,0x2133,0x3321,0x1133,0x3321,
0x3333,0x3333,0x1333,0x3211,0x1333,0x3322,0x1333,0x3332, //a2
0x1333,0x3332,0x2333,0x3332,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3321, //a3
0x3333,0x3321,0x3333,0x3321,0x1133,0x3321,0x2233,0x3322,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //a4
0x3333,0x3333,0x3333,0x3333,0x2133,0x3333,0x1333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //a5
0x1333,0x3332,0x2333,0x3332,0x3333,0x3333,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x2122, //a6
0x1113,0x2111,0x2223,0x2122,0x3333,0x3213,0x1113,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1113,0x3321, //a7
0x2223,0x3321,0x2133,0x3321,0x2133,0x3332,0x3213,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3321, //a8
0x1133,0x3332,0x2111,0x3333,0x2122,0x3333,0x2133,0x3333,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1333,0x3332, //a9
0x1113,0x3211,0x2213,0x3212,0x3323,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //aa
0x1133,0x3321,0x1233,0x3332,0x1333,0x3332,0x1113,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3321, //ab
0x1113,0x3211,0x2223,0x3321,0x1333,0x3321,0x2113,0x3321,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1213,0x3211, //ac
0x2111,0x3212,0x2122,0x3323,0x1333,0x3332,0x1333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //ad
0x1113,0x3321,0x2223,0x3321,0x3333,0x3321,0x1113,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1133,0x3211, //ae
0x2233,0x3212,0x1133,0x3211,0x2233,0x3212,0x1133,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //af
0x1213,0x3212,0x2323,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //b0
0x3333,0x3333,0x1113,0x3211,0x2223,0x3322,0x3333,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x2222,0x3212, //b1
0x2133,0x3213,0x2133,0x3321,0x2133,0x3332,0x3211,0x3333,
0x3333,0x3333,0x3333,0x2133,0x3333,0x3213,0x1333,0x3321, //b2
0x2113,0x3321,0x3223,0x3321,0x3333,0x3321,0x3333,0x3321,
0x3333,0x3333,0x1333,0x3332,0x1113,0x2111,0x2213,0x2122, //b3
0x3323,0x2133,0x3333,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1113,0x3211,0x1223,0x3322, //b4
0x1333,0x3332,0x1333,0x3332,0x1333,0x3332,0x1111,0x2111,
0x3333,0x3333,0x3333,0x3213,0x1113,0x2111,0x2223,0x3212, //b5
0x3333,0x3211,0x1333,0x3212,0x1333,0x3212,0x2113,0x3213,
0x3333,0x3333,0x1333,0x3332,0x1113,0x2111,0x1223,0x2122, //b6
0x1333,0x2132,0x2133,0x2133,0x2133,0x2133,0x3213,0x3213,
0x3333,0x3333,0x1333,0x3332,0x1113,0x2111,0x2223,0x3221, //b7
0x3333,0x3321,0x1113,0x1111,0x2223,0x2212,0x3333,0x3213,
0x3333,0x3333,0x1133,0x2111,0x2133,0x2122,0x3213,0x2133, //b8
0x3323,0x3213,0x3333,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3213,0x3333,0x1113,0x2111,0x2213,0x3212, //b9
0x3321,0x3213,0x3332,0x3321,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x2122, //ba
0x3333,0x2133,0x3333,0x2133,0x3333,0x2133,0x1113,0x2111,
0x3333,0x3333,0x3213,0x3213,0x1111,0x2111,0x2212,0x3212, //bb
0x3213,0x3213,0x3323,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x2113,0x2133,0x3223,0x2133, //bc
0x2113,0x2133,0x3223,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x3212, //bd
0x3333,0x3321,0x3333,0x3321,0x1333,0x3212,0x2113,0x2133,
0x3333,0x3333,0x2133,0x3333,0x1133,0x2111,0x2111,0x2122, //be
0x2122,0x3213,0x2133,0x3323,0x2133,0x3333,0x1133,0x2111,
0x3333,0x3333,0x3333,0x3333,0x3213,0x2133,0x3213,0x2133, //bf
0x2123,0x3213,0x3233,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x1133,0x2111,0x2133,0x2122,0x2133,0x2133, //c0
0x1213,0x2111,0x2323,0x2122,0x3333,0x3213,0x1133,0x3321,
0x3333,0x3333,0x3333,0x3213,0x1113,0x3321,0x2223,0x3321, //c1
0x1111,0x2111,0x2222,0x3221,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1213,0x2132,0x1213,0x2132, //c2
0x2323,0x2133,0x3333,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x3333,0x1113,0x3211,0x2223,0x3322,0x1111,0x2111, //c3
0x2222,0x3221,0x3333,0x3321,0x1333,0x3332,0x2113,0x3333,
0x3333,0x3333,0x2133,0x3333,0x2133,0x3333,0x2133,0x3333, //c4
0x1133,0x3332,0x2133,0x3211,0x2133,0x3322,0x2133,0x3333,
0x3333,0x3333,0x3333,0x3321,0x1111,0x2111,0x2222,0x3221, //c5
0x3333,0x3321,0x3333,0x3321,0x1333,0x3332,0x2113,0x3333,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2233,0x3322, //c6
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x2222,0x3212, //c7
0x3133,0x3321,0x1233,0x3332,0x2133,0x3321,0x3211,0x3213,
0x3333,0x3333,0x1333,0x3332,0x1111,0x2111,0x2222,0x3212, //c8
0x3333,0x3321,0x1133,0x3212,0x1211,0x2132,0x1322,0x3232,
0x3333,0x3333,0x3333,0x3213,0x3333,0x3213,0x3333,0x3213, //c9
0x3333,0x3321,0x3333,0x3321,0x1333,0x3332,0x2113,0x3333,
0x3333,0x3333,0x1333,0x3332,0x3333,0x3321,0x3213,0x3213, //ca
0x3213,0x3213,0x3321,0x2133,0x3321,0x2133,0x3321,0x2133,
0x3333,0x3333,0x3213,0x2133,0x3213,0x3211,0x1113,0x3322, //cb
0x2213,0x3333,0x3213,0x3333,0x3213,0x3333,0x1133,0x2111,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x2222,0x2122, //cc
0x3333,0x3213,0x3333,0x3213,0x3333,0x3321,0x1113,0x3332,
0x3333,0x3333,0x3333,0x3333,0x2133,0x3333,0x1213,0x3332, //cd
0x3321,0x3321,0x3332,0x3213,0x3333,0x2133,0x3333,0x3233,
0x3333,0x3333,0x1333,0x3332,0x1111,0x2111,0x1222,0x3222, //ce
0x1213,0x3212,0x1213,0x2132,0x1321,0x2132,0x1321,0x2132,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x2222,0x2122, //cf
0x3213,0x3213,0x2133,0x3321,0x1333,0x3332,0x3333,0x3321,
0x3333,0x3333,0x3113,0x3333,0x1223,0x3311,0x2333,0x2122, //d0
0x1133,0x3231,0x2233,0x3212,0x1113,0x3322,0x2223,0x2111,
0x3333,0x3333,0x1333,0x3332,0x2133,0x3333,0x3213,0x3333, //d1
0x3213,0x3213,0x3321,0x2133,0x3321,0x2133,0x1111,0x2111,
0x3333,0x3333,0x3333,0x3213,0x3213,0x3213,0x2133,0x3321, //d2
0x1333,0x3332,0x1333,0x3332,0x2133,0x3321,0x3211,0x3213,
0x3333,0x3333,0x3333,0x3333,0x1111,0x2111,0x2122,0x3222, //d3
0x1111,0x2111,0x2122,0x3222,0x2133,0x3333,0x1133,0x2111,
0x3333,0x3333,0x2133,0x3333,0x1133,0x2111,0x2111,0x2122, //d4
0x2122,0x3213,0x2133,0x3323,0x1333,0x3332,0x1333,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1113,0x3321,0x2223,0x3321, //d5
0x3333,0x3321,0x3333,0x3321,0x3333,0x3321,0x1111,0x2111,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2223,0x2122, //d6
0x1113,0x2111,0x2223,0x2122,0x3333,0x2133,0x1113,0x2111,
0x3333,0x3333,0x1113,0x3211,0x2223,0x3322,0x1111,0x2111, //d7
0x2222,0x2122,0x3333,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x3333,0x3213,0x3213,0x3213,0x3213,0x3213,0x3213, //d8
0x3213,0x3213,0x3323,0x3213,0x3333,0x3321,0x1113,0x3332,
0x3333,0x3333,0x1333,0x3332,0x1213,0x3332,0x1213,0x3332, //d9
0x1213,0x2132,0x1213,0x2132,0x1213,0x3212,0x1321,0x3321,
0x3333,0x3333,0x3213,0x3333,0x3213,0x3333,0x3213,0x3333, //da
0x3213,0x3213,0x3213,0x3213,0x3213,0x3321,0x1113,0x3332,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2213,0x2122, //db
0x3213,0x2133,0x3213,0x2133,0x3213,0x2133,0x1113,0x2111,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2111,0x2213,0x2122, //dc
0x3323,0x2133,0x3333,0x2133,0x3333,0x3213,0x1133,0x3321,
0x3333,0x3333,0x3333,0x3333,0x1113,0x2132,0x2223,0x2133, //dd
0x3333,0x2133,0x3333,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x1313,0x1333,0x2322,0x1113,0x2111,0x1223,0x2122, //de
0x1333,0x2132,0x2133,0x2133,0x2133,0x2133,0x3213,0x3213,
0x3333,0x1313,0x1333,0x2322,0x1113,0x2111,0x2223,0x3221, //df
0x3333,0x3321,0x1113,0x1111,0x2223,0x2212,0x3333,0x3213,
0x3333,0x1213,0x3333,0x2323,0x1133,0x2111,0x2133,0x2122, //e0
0x3213,0x3213,0x3323,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x1313,0x3213,0x2323,0x1113,0x2111,0x2213,0x3212, //e1
0x3321,0x3213,0x3332,0x3321,0x3333,0x3321,0x1133,0x3332,
0x3333,0x1313,0x3333,0x2323,0x1113,0x2111,0x2223,0x2122, //e2
0x3333,0x2133,0x3333,0x2133,0x3333,0x2133,0x1113,0x2111,
0x3333,0x1313,0x3333,0x2323,0x3213,0x3213,0x1111,0x2111, //e3
0x2212,0x3212,0x3213,0x3213,0x3323,0x3321,0x1133,0x3332,
0x3333,0x1313,0x3333,0x2323,0x2113,0x2133,0x3223,0x2133, //e4
0x2113,0x2133,0x3223,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x1313,0x3333,0x2323,0x1113,0x2111,0x2223,0x3212, //e5
0x3333,0x3321,0x3333,0x3321,0x1333,0x3212,0x2113,0x2133,
0x3333,0x1313,0x2133,0x2323,0x1133,0x2111,0x2111,0x2122, //e6
0x2122,0x3213,0x2133,0x3323,0x2133,0x3333,0x1133,0x2111,
0x3333,0x1313,0x3333,0x2323,0x3213,0x2133,0x3213,0x2133, //e7
0x2123,0x3213,0x3233,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x1313,0x3333,0x2323,0x1133,0x2111,0x2133,0x2122, //e8
0x1213,0x2111,0x2323,0x2122,0x3333,0x3213,0x1133,0x3321,
0x3333,0x1313,0x3333,0x2323,0x1113,0x3211,0x2223,0x3321, //e9
0x1111,0x2111,0x2222,0x3221,0x3333,0x3321,0x1133,0x3332,
0x3333,0x1313,0x3333,0x2323,0x1213,0x2132,0x1213,0x2132, //ea
0x2323,0x2133,0x3333,0x2133,0x3333,0x3213,0x1113,0x3321,
0x3333,0x1313,0x3333,0x2323,0x1113,0x3211,0x2223,0x3322, //eb
0x1111,0x2111,0x2222,0x3221,0x3333,0x3321,0x1113,0x3332,
0x3333,0x3333,0x2133,0x1313,0x2133,0x2323,0x2133,0x3333, //ec
0x1133,0x3333,0x2133,0x3211,0x2133,0x3322,0x2133,0x3333,
0x3333,0x1313,0x1333,0x2323,0x3333,0x3331,0x3213,0x3213, //ed
0x3213,0x3213,0x3321,0x2133,0x3321,0x2133,0x3321,0x2133,
0x3333,0x1313,0x3213,0x2323,0x3213,0x2111,0x1113,0x3222, //ee
0x2213,0x3333,0x3213,0x3333,0x3213,0x3333,0x1123,0x2111,
0x3333,0x1313,0x3333,0x2323,0x1111,0x2111,0x2222,0x2122, //ef
0x3333,0x3213,0x3333,0x3213,0x3333,0x3321,0x1113,0x3332,
0x3333,0x3333,0x3333,0x1313,0x2133,0x2323,0x1213,0x3332, //f0
0x3321,0x3321,0x3332,0x3213,0x3333,0x2133,0x3333,0x3233,
0x3333,0x1313,0x1333,0x2323,0x1111,0x2111,0x1222,0x3222, //f1
0x1213,0x3212,0x1213,0x2132,0x1321,0x2132,0x1321,0x2132,
0x3333,0x1313,0x1333,0x2322,0x1113,0x2111,0x2213,0x2122, //f2
0x3323,0x2133,0x3333,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3133,0x1333,0x1212,0x3333,0x2121,0x3213,0x3213, //f3
0x3213,0x3213,0x3321,0x2133,0x3321,0x2133,0x3321,0x2133,
0x3333,0x3133,0x3213,0x1213,0x3213,0x2111,0x1113,0x3222, //f4
0x2213,0x3333,0x3213,0x3333,0x3213,0x3333,0x1133,0x2111,
0x3333,0x3133,0x3333,0x1213,0x1111,0x2111,0x2222,0x2122, //f5
0x3333,0x3213,0x3333,0x3213,0x3333,0x3321,0x1113,0x3332,
0x3333,0x3133,0x3333,0x1213,0x2133,0x2123,0x1213,0x3232, //f6
0x3321,0x3321,0x3332,0x3213,0x3333,0x2133,0x3333,0x3233,
0x3333,0x3133,0x1333,0x1212,0x1111,0x2111,0x1222,0x3222, //f7
0x1213,0x3212,0x1213,0x2132,0x1321,0x2132,0x1321,0x2132,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3211,0x2123,0x3322, //f8
0x1113,0x2113,0x1223,0x3221,0x2133,0x3332,0x1133,0x2111,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3321,0x2123,0x2132, //f9
0x1113,0x3211,0x2121,0x2121,0x1321,0x2132,0x2113,0x3213,
0x3333,0x3333,0x3213,0x3333,0x3213,0x3213,0x3213,0x2133, //fa
0x3213,0x2133,0x3213,0x2133,0x1213,0x3232,0x2133,0x3333,
0x3333,0x3333,0x1133,0x3321,0x2233,0x3332,0x1333,0x3211, //fb
0x2113,0x2122,0x3223,0x2133,0x3333,0x3213,0x1133,0x3321,
0x3333,0x3333,0x1133,0x3321,0x2233,0x3332,0x1113,0x3211, //fc
0x2223,0x3321,0x1333,0x3332,0x2133,0x3321,0x3213,0x2113,
0x3333,0x3333,0x2133,0x2133,0x1133,0x2121,0x2113,0x3232, //fd
0x1123,0x3211,0x2113,0x2122,0x2121,0x2133,0x2113,0x3213,
0x3333,0x3333,0x3333,0x3321,0x2133,0x3213,0x1111,0x2132, //fe
0x2122,0x2121,0x3213,0x3321,0x3321,0x3321,0x1132,0x3332,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3211,0x2223,0x3321, //ff
0x1133,0x2111,0x2233,0x3212,0x3313,0x3323,0x1133,0x3211,
0x3333,0x3333,0x3333,0x3213,0x3333,0x3321,0x1333,0x3332, //100
0x2133,0x3333,0x1333,0x3332,0x3333,0x3321,0x3333,0x3213,
0x3333,0x3333,0x3333,0x3213,0x1213,0x2111,0x2213,0x3212, //101
0x3213,0x3213,0x3213,0x3213,0x2133,0x3213,0x3233,0x3321,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2233,0x2122, //102
0x3333,0x3213,0x3333,0x3323,0x3213,0x3333,0x1133,0x2111,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3211,0x2223,0x3321, //103
0x3333,0x3212,0x3333,0x3213,0x3213,0x3333,0x1123,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3213,0x3333,0x3213,0x3333, //104
0x3213,0x3333,0x3213,0x3333,0x3213,0x3213,0x1123,0x3321,
0x3333,0x3333,0x3333,0x3321,0x1113,0x2111,0x2223,0x3221, //105
0x1133,0x3321,0x2133,0x3321,0x1333,0x3321,0x1113,0x3332,
0x3333,0x3333,0x3333,0x3333,0x3213,0x3321,0x1113,0x2111, //106
0x3211,0x3321,0x3212,0x3321,0x3213,0x2133,0x1133,0x3211,
0x3333,0x3333,0x2133,0x2133,0x2133,0x2133,0x3233,0x3213, //107
0x1113,0x2111,0x1223,0x3222,0x2133,0x3333,0x1333,0x2111,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3211,0x2123,0x3322, //108
0x3213,0x2111,0x3213,0x3222,0x1213,0x3332,0x3321,0x2111,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3211,0x2123,0x3322, //109
0x1213,0x3311,0x2113,0x2122,0x3223,0x2133,0x1333,0x3211,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2211,0x2122, //10a
0x3322,0x2133,0x3333,0x2133,0x3333,0x3213,0x1133,0x3321,
0x3333,0x3333,0x3333,0x2113,0x1133,0x3211,0x2211,0x3321, //10b
0x1322,0x3332,0x1333,0x3332,0x3333,0x3321,0x3333,0x2113,
0x3333,0x3333,0x3213,0x3333,0x3213,0x2133,0x2133,0x3211, //10c
0x1133,0x3322,0x2213,0x3333,0x3213,0x3333,0x1133,0x2111,
0x3333,0x3333,0x2133,0x3333,0x1111,0x2112,0x2212,0x3223, //10d
0x3213,0x3213,0x1321,0x3211,0x2132,0x2112,0x1333,0x3221,
0x3333,0x3333,0x3333,0x3333,0x1213,0x2111,0x2213,0x3222, //10e
0x3213,0x3333,0x3213,0x3333,0x3213,0x3321,0x2133,0x2113,
0x3333,0x3333,0x3333,0x3321,0x3213,0x3321,0x1213,0x3211, //10f
0x2113,0x2121,0x1121,0x2112,0x2121,0x2121,0x3213,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3213,0x3211,0x1211,0x2122, //110
0x2112,0x2133,0x3213,0x2111,0x3211,0x2121,0x3212,0x3211,
0x3333,0x3333,0x3333,0x3333,0x1133,0x3211,0x2113,0x2122, //111
0x2121,0x2133,0x2121,0x2133,0x2121,0x2133,0x3213,0x3213,
0x3333,0x3333,0x3333,0x3213,0x1121,0x2111,0x2221,0x3212, //112
0x3321,0x3213,0x1321,0x3211,0x2121,0x2112,0x1332,0x3221,
0x3333,0x3333,0x2133,0x3333,0x2111,0x3213,0x3212,0x2113, //113
0x3321,0x3213,0x3321,0x3213,0x3321,0x3321,0x1113,0x3332,
0x3333,0x3333,0x1133,0x3333,0x2233,0x3321,0x3333,0x3332, //114
0x1213,0x3332,0x3321,0x2121,0x3321,0x2121,0x1132,0x3232,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x1133,0x3332, //115
0x2213,0x3321,0x3321,0x3213,0x3332,0x2133,0x3333,0x2233,
0x3333,0x3333,0x1321,0x2111,0x2321,0x3212,0x1321,0x2111, //116
0x2321,0x3212,0x1321,0x3211,0x2121,0x2112,0x1213,0x3221,
0x3333,0x3333,0x1113,0x3211,0x2223,0x3321,0x1113,0x3211, //117
0x2223,0x3321,0x1113,0x3321,0x2221,0x3211,0x1113,0x3322,
0x3333,0x3333,0x1113,0x3321,0x1223,0x3332,0x2133,0x3213, //118
0x1113,0x3211,0x2121,0x2112,0x3211,0x3213,0x3322,0x3321,
0x3333,0x3333,0x2133,0x3333,0x1111,0x3212,0x2122,0x2133, //119
0x2113,0x3333,0x2121,0x2133,0x3213,0x2133,0x1133,0x3211,
0x3333,0x3333,0x3333,0x3321,0x1213,0x3211,0x2113,0x2121, //11a
0x1211,0x2132,0x1121,0x2132,0x2121,0x2133,0x3213,0x3213,
0x3333,0x3333,0x1333,0x3332,0x1113,0x3321,0x2123,0x3332, //11b
0x1113,0x3321,0x2123,0x2132,0x2133,0x2133,0x1333,0x3211,
0x3333,0x3333,0x3333,0x3321,0x1213,0x3211,0x2113,0x2121, //11c
0x3211,0x2132,0x2122,0x3213,0x2133,0x3323,0x1333,0x3332,
0x3333,0x3333,0x1333,0x3332,0x1321,0x3211,0x1121,0x2122, //11d
0x1211,0x2132,0x1321,0x2132,0x1332,0x3212,0x2133,0x3323,
0x3333,0x3333,0x1333,0x3332,0x1333,0x3211,0x1333,0x3322, //11e
0x1333,0x3332,0x1113,0x3321,0x1221,0x3212,0x2113,0x3323,
0x3333,0x3333,0x1133,0x3321,0x2233,0x3332,0x2133,0x3211, //11f
0x1213,0x2122,0x2113,0x2133,0x3223,0x2133,0x1333,0x3211,
0x3333,0x3333,0x2133,0x3333,0x3213,0x3213,0x3213,0x3213, //120
0x2113,0x3213,0x3223,0x3213,0x3333,0x3321,0x1133,0x3332,
0x3333,0x3333,0x1113,0x3211,0x2223,0x3321,0x1333,0x3211, //121
0x2113,0x2122,0x1221,0x2121,0x2132,0x2121,0x1333,0x3211,
0x3333,0x3333,0x3333,0x3211,0x1213,0x3212,0x1211,0x3212, //122
0x2112,0x3213,0x3213,0x3213,0x3211,0x3213,0x3212,0x2133,
0x3333,0x3333,0x1333,0x3211,0x2113,0x3321,0x1223,0x3332, //123
0x1133,0x3211,0x2211,0x2122,0x3322,0x2133,0x1333,0x3211,
0x3333,0x3333,0x3333,0x3333,0x3213,0x3311,0x1211,0x2122, //124
0x2112,0x2133,0x3213,0x2133,0x3211,0x2133,0x3212,0x3211,
0x3333,0x3333,0x3333,0x3333,0x1333,0x3332,0x1333,0x3332, //125
0x2133,0x3333,0x1133,0x3332,0x1213,0x2132,0x3321,0x3211,
0x3333,0x1313,0x3333,0x2323,0x2133,0x3213,0x1111,0x2132, //126
0x2122,0x2121,0x3213,0x3221,0x3321,0x3321,0x1132,0x3332,
0x3333,0x1313,0x1333,0x2322,0x1113,0x3211,0x2223,0x3321, //127
0x1133,0x2111,0x2233,0x3212,0x3313,0x3323,0x1123,0x3211,
0x3333,0x1313,0x3333,0x2323,0x3333,0x3321,0x1333,0x3332, //128
0x2133,0x3333,0x1233,0x3333,0x2333,0x3331,0x3333,0x3312,
0x3333,0x1313,0x3333,0x2323,0x1213,0x2111,0x3213,0x3213, //129
0x3213,0x3213,0x3213,0x3213,0x2123,0x3213,0x3233,0x3321,
0x3333,0x1313,0x3333,0x2323,0x1133,0x3211,0x2233,0x2122, //12a
0x3333,0x3213,0x3333,0x3323,0x3213,0x3333,0x1123,0x3111,
0x3333,0x1313,0x1333,0x2322,0x1113,0x3211,0x2223,0x3321, //12b
0x3333,0x3212,0x3333,0x3213,0x3213,0x3323,0x1123,0x3211,
0x3333,0x3333,0x3333,0x3131,0x3213,0x3232,0x3213,0x3333, //12c
0x3213,0x3333,0x3213,0x3333,0x3213,0x3213,0x1133,0x3321,
0x3333,0x1313,0x3333,0x2321,0x1113,0x2111,0x2223,0x3321, //12d
0x1133,0x3321,0x2133,0x3321,0x1333,0x3321,0x1113,0x3332,
0x3333,0x1313,0x3333,0x2323,0x3213,0x3321,0x1113,0x2111, //12e
0x2211,0x3221,0x3212,0x3321,0x3213,0x2132,0x1133,0x3211,
0x3333,0x1313,0x2133,0x2323,0x2133,0x2133,0x3233,0x3213, //12f
0x1113,0x3111,0x1223,0x3222,0x2133,0x3333,0x1233,0x2111,
0x3333,0x1313,0x1333,0x2322,0x1113,0x3211,0x2123,0x3322, //130
0x3213,0x2111,0x3213,0x3222,0x1213,0x3332,0x2321,0x2111,
0x3333,0x1313,0x1333,0x2322,0x1113,0x3211,0x2123,0x3322, //131
0x1213,0x3211,0x2113,0x2122,0x3223,0x2133,0x1333,0x3211,
0x3333,0x1313,0x3333,0x2323,0x1133,0x3211,0x2211,0x2122, //132
0x3322,0x2133,0x3333,0x2133,0x3333,0x3213,0x1133,0x3321,
0x3333,0x1313,0x3333,0x2323,0x1133,0x2111,0x2211,0x3221, //133
0x1322,0x3332,0x1333,0x3332,0x3333,0x3321,0x3333,0x2113,
0x3333,0x1313,0x3213,0x2323,0x3213,0x2133,0x2133,0x3211, //134
0x1133,0x3322,0x2213,0x3333,0x3213,0x3333,0x1133,0x2111,
0x3333,0x1313,0x3333,0x2323,0x1121,0x2111,0x2221,0x3212, //135
0x3321,0x3213,0x1321,0x3211,0x2121,0x2112,0x1332,0x3221,
0x3333,0x1313,0x2133,0x2323,0x2111,0x3213,0x3212,0x2113, //136
0x3321,0x3213,0x3321,0x3213,0x3321,0x3321,0x1113,0x3332,
0x3333,0x1313,0x1133,0x2323,0x2233,0x3321,0x3333,0x3332, //137
0x1213,0x3332,0x2321,0x2121,0x3321,0x2121,0x1132,0x3232,
0x3333,0x3333,0x3333,0x3131,0x3333,0x3232,0x1133,0x3332, //138
0x2213,0x3321,0x3321,0x3213,0x3332,0x2133,0x3333,0x3233,
0x3333,0x1313,0x1321,0x2321,0x2321,0x3212,0x1321,0x2111, //139
0x2321,0x3212,0x1321,0x3211,0x2121,0x2112,0x1213,0x3221,
0x3333,0x3133,0x3333,0x1213,0x1121,0x2111,0x2221,0x3212, //13a
0x3321,0x3213,0x1321,0x3211,0x2121,0x2112,0x1332,0x3221,
0x3333,0x3133,0x2133,0x1213,0x2111,0x2123,0x3213,0x1113, //13b
0x3321,0x2213,0x3321,0x3213,0x3321,0x3321,0x1113,0x3332,
0x3333,0x3133,0x1133,0x1213,0x2233,0x2121,0x3333,0x3232, //13c
0x1213,0x3332,0x3321,0x2121,0x3321,0x2121,0x1132,0x3232,
0x3333,0x3313,0x3333,0x2121,0x3333,0x3212,0x1133,0x3322, //13d
0x2213,0x3321,0x3321,0x3213,0x3332,0x2133,0x3333,0x3233,
0x3333,0x3133,0x1321,0x1211,0x2321,0x2112,0x1321,0x2111, //13e
0x2321,0x3212,0x1321,0x3211,0x2121,0x2112,0x1213,0x3221,
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333, //13f
0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,0x3333,
};
*/

View File

@ -0,0 +1,335 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: myFontequ.h
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$
*---------------------------------------------------------------------------*/
#ifndef __MY_FONT_H__
#define __MY_FONT_H__
// 文字コードの定義
#define EOM_ 0x00 // 終了コード
// オーナー情報編集用ボタン----------------------
#define CODE_BUTTON_TOP_ 0x200
#define VAR_BUTTON1_ CODE_BUTTON_TOP_
#define VAR_BUTTON2_ (CODE_BUTTON_TOP_ + 1)
#define DEL_BUTTON_ (CODE_BUTTON_TOP_ + 2)
#define CANCEL_BUTTON_ (CODE_BUTTON_TOP_ + 3)
#define OK_BUTTON_ (CODE_BUTTON_TOP_ + 4)
#define CODE_BUTTON_BOTTOM_ (CODE_BUTTON_TOP_ + 5)
/*
// ひらがな----------------------------------------
#define a_ 0x0f9 // "あ"
#define i_ 0x0fa // "い"
#define u_ 0x0fb // "う"
#define e_ 0x0fc // "え"
#define o_ 0x0fd // "お"
#define ka_ 0x0fe // "か"
#define ki_ 0x0ff // "き"
#define ku_ 0x100 // "く"
#define ke_ 0x101 // "け"
#define ko_ 0x102 // "こ"
#define sa_ 0x103 // "さ"
#define si_ 0x104 // "し"
#define su_ 0x105 // "す"
#define se_ 0x106 // "せ"
#define so_ 0x107 // "そ"
#define ta_ 0x108 // "た"
#define ti_ 0x109 // "ち"
#define tu_ 0x10a // "つ"
#define te_ 0x10b // "て"
#define to_ 0x10c // "と"
#define na_ 0x10d // "な"
#define ni_ 0x10e // "に"
#define nu_ 0x10f // "ぬ"
#define ne_ 0x110 // "ね"
#define no_ 0x111 // "の"
#define ha_ 0x112 // "は"
#define hi_ 0x113 // "ひ"
#define hu_ 0x114 // "ふ"
#define he_ 0x115 // "へ"
#define ho_ 0x116 // "ほ"
#define ma_ 0x117 // "ま"
#define mi_ 0x118 // "み"
#define mu_ 0x119 // "む"
#define me_ 0x11a // "め"
#define mo_ 0x11b // "も"
#define ya_ 0x11c // "や"
#define yu_ 0x11d // "ゆ"
#define yo_ 0x11e // "よ"
#define ra_ 0x11f // "ら"
#define ri_ 0x120 // "り"
#define ru_ 0x121 // "る"
#define re_ 0x122 // "れ"
#define ro_ 0x123 // "ろ"
#define wa_ 0x124 // "わ"
#define wo_ 0x0f8 // "を"
#define n_ 0x125 // "ん"
#define ga_ 0x126 // "が"
#define gi_ 0x127 // "ぎ"
#define gu_ 0x128 // "ぐ"
#define ge_ 0x129 // "げ"
#define go_ 0x12a // "ご"
#define za_ 0x12b // "ざ"
#define zi_ 0x12c // "じ"
#define zu_ 0x12d // "ず"
#define ze_ 0x12e // "ぜ"
#define zo_ 0x12f // "ぞ"
#define da_ 0x130 // "だ"
#define di_ 0x131 // "ぢ"
#define du_ 0x132 // "づ"
#define de_ 0x133 // "で"
#define do_ 0x134 // "ど"
#define ba_ 0x135 // "ば"
#define bi_ 0x136 // "び"
#define bu_ 0x137 // "ぶ"
#define be_ 0x138 // "べ"
#define bo_ 0x139 // "ぼ"
#define pa_ 0x13a // "ぱ"
#define pi_ 0x13b // "ぴ"
#define pu_ 0x13c // "ぷ"
#define pe_ 0x13d // "ぺ"
#define po_ 0x13e // "ぽ"
#define aa_ 0x08d // "ぁ"
#define ii_ 0x08e // "ぃ"
#define uu_ 0x08f // "ぅ"
#define ee_ 0x090 // "ぇ"
#define oo_ 0x091 // "ぉ"
#define yya_ 0x092 // "ゃ"
#define yyu_ 0x093 // "ゅ"
#define yyo_ 0x094 // "ょ"
#define ttu_ 0x095 // "っ"
// カタカナ----------------------------------------
#define A_ 0x0b1 // "ア"
#define I_ 0x0b2 // "イ"
#define U_ 0x0b3 // "ウ"
#define E_ 0x0b4 // "エ"
#define O_ 0x0b5 // "オ"
#define KA_ 0x0b6 // "カ"
#define KI_ 0x0b7 // "キ"
#define KU_ 0x0b8 // "ク"
#define KE_ 0x0b9 // "ケ"
#define KO_ 0x0ba // "コ"
#define SA_ 0x0bb // "サ"
#define SI_ 0x0bc // "シ"
#define SU_ 0x0bd // "ス"
#define SE_ 0x0be // "セ"
#define SO_ 0x0bf // "ソ"
#define TA_ 0x0c0 // "タ"
#define TI_ 0x0c1 // "チ"
#define TU_ 0x0c2 // "ツ"
#define TE_ 0x0c3 // "テ"
#define TO_ 0x0c4 // "ト"
#define NA_ 0x0c5 // "ナ"
#define NI_ 0x0c6 // "ニ"
#define NU_ 0x0c7 // "ヌ"
#define NE_ 0x0c8 // "ネ"
#define NO_ 0x0c9 // ""
#define HA_ 0x0ca // "ハ"
#define HI_ 0x0cb // "ヒ"
#define HU_ 0x0cc // "フ"
#define HE_ 0x0cd // "ヘ"
#define HO_ 0x0ce // "ホ"
#define MA_ 0x0cf // "マ"
#define MI_ 0x0d0 // "ミ"
#define MU_ 0x0d1 // "ム"
#define ME_ 0x0d2 // "メ"
#define MO_ 0x0d3 // "モ"
#define YA_ 0x0d4 // "ヤ"
#define YU_ 0x0d5 // "ユ"
#define YO_ 0x0d6 // "ヨ"
#define RA_ 0x0d7 // "ラ"
#define RI_ 0x0d8 // "リ"
#define RU_ 0x0d9 // "ル"
#define RE_ 0x0da // "レ"
#define RO_ 0x0db // "ロ"
#define WA_ 0x0dc // "ワ"
#define WO_ 0x0a6 // "ヲ"
#define N_ 0x0dd // "ン"
#define GA_ 0x0de // "ガ"
#define GI_ 0x0df // "ギ"
#define GU_ 0x0e0 // "グ"
#define GE_ 0x0e1 // "ゲ"
#define GO_ 0x0e2 // "ゴ"
#define ZA_ 0x0e3 // "ザ"
#define ZI_ 0x0e4 // "ジ"
#define ZU_ 0x0e5 // "ズ"
#define ZE_ 0x0e6 // "ゼ"
#define ZO_ 0x0e7 // "ゾ"
#define DA_ 0x0e8 // "ダ"
#define DI_ 0x0e9 // "ヂ"
#define DU_ 0x0ea // "ヅ"
#define DE_ 0x0eb // "デ"
#define DO_ 0x0ec // "ド"
#define BA_ 0x0ed // "バ"
#define BI_ 0x0ee // "ビ"
#define BU_ 0x0ef // "ブ"
#define BE_ 0x0f0 // "ベ"
#define BO_ 0x0f1 // "ボ"
#define VU_ 0x0f2 // "ヴ"
#define PA_ 0x0f3 // "パ"
#define PI_ 0x0f4 // "ピ"
#define PU_ 0x0f5 // "プ"
#define PE_ 0x0f6 // "ペ"
#define PO_ 0x0f7 // "ポ"
#define AA_ 0x0a7 // "ァ"
#define II_ 0x0a8 // "ィ"
#define UU_ 0x0a9 // "ゥ"
#define EE_ 0x0aa // "ェ"
#define OO_ 0x0ab // "ォ"
#define YYA_ 0x0ac // "ャ"
#define YYU_ 0x0ad // "ュ"
#define YYO_ 0x0ae // "ョ"
#define TTU_ 0x0af // "ッ"
// アルファベット大文字----------------------------
#define A__ 0x041 // ""
#define B__ 0x042 // ""
#define C__ 0x043 // ""
#define D__ 0x044 // ""
#define E__ 0x045 // ""
#define F__ 0x046 // ""
#define G__ 0x047 // ""
#define H__ 0x048 // ""
#define I__ 0x049 // ""
#define J__ 0x04a // ""
#define K__ 0x04b // ""
#define L__ 0x04c // ""
#define M__ 0x04d // ""
#define N__ 0x04e // ""
#define O__ 0x04f // ""
#define P__ 0x050 // ""
#define Q__ 0x051 // ""
#define R__ 0x052 // ""
#define S__ 0x053 // ""
#define T__ 0x054 // ""
#define U__ 0x055 // ""
#define V__ 0x056 // ""
#define W__ 0x057 // ""
#define X__ 0x058 // ""
#define Y__ 0x059 // ""
#define Z__ 0x05a // ""
// アルファベット小文字----------------------------
#define a__ 0x061 // ""
#define b__ 0x062 // ""
#define c__ 0x063 // ""
#define d__ 0x064 // ""
#define e__ 0x065 // ""
#define f__ 0x066 // ""
#define g__ 0x067 // ""
#define h__ 0x068 // ""
#define i__ 0x069 // ""
#define j__ 0x06a // ""
#define k__ 0x06b // ""
#define l__ 0x06c // ""
#define m__ 0x06d // ""
#define n__ 0x06e // ""
#define o__ 0x06f // ""
#define p__ 0x070 // ""
#define q__ 0x071 // ""
#define r__ 0x072 // ""
#define s__ 0x073 // ""
#define t__ 0x074 // ""
#define u__ 0x075 // ""
#define v__ 0x076 // ""
#define w__ 0x077 // ""
#define x__ 0x078 // ""
#define y__ 0x079 // ""
#define z__ 0x07a // ""
// 数字--------------------------------------------
#define n0_ 0x030 // ""
#define n1_ 0x031 // ""
#define n2_ 0x032 // ""
#define n3_ 0x033 // ""
#define n4_ 0x034 // ""
#define n5_ 0x035 // ""
#define n6_ 0x036 // ""
#define n7_ 0x037 // ""
#define n8_ 0x038 // ""
#define n9_ 0x039 // ""
// 記号--------------------------------------------
#define spc_ 0x020 // " "
#define bicri_ 0x021 // ""
#define cyoncyon_ 0x022 // "”"
#define sharp_ 0x023 // ""
#define dollar_ 0x024 // ""
#define percent_ 0x025 // ""
#define and_ 0x026 // ""
#define cyon_ 0x027 // ""
#define kakko_ 0x028 // ""
#define kakkot_ 0x029 // ""
#define kome_ 0x02a // ""
#define tasu_ 0x02b // ""
#define comma_ 0x02c // ""
#define hiku_ 0x02d // ""
#define period_ 0x02e // ""
#define sura_ 0x02f // ""
#define colon_ 0x03a // ""
#define semicolon_ 0x03b // ""
#define dainari_ 0x03c // ""
#define equal_ 0x03d // ""
#define syounari_ 0x03e // ""
#define hate_ 0x03f // ""
#define atomark_ 0x040 // ""
#define dkakko_ 0x05b // ""
#define bsura_ 0x05c // ""
#define dkakkot_ 0x05d // ""
#define yama_ 0x05e // ""
#define uscore_ 0x05f // "_"
#define bcyon_ 0x060 // ""
#define ckakko_ 0x07b // ""
#define mataha_ 0x07c // ""
#define ckakkot_ 0x07d // ""
#define kara_ 0x07e // ""
#define kten_ 0x0a1 // "。"
#define k_kakko_ 0x0a2 // "「"
#define k_kakkot_ 0x0a3 // "」"
#define tten_ 0x0a4 // "、"
#define nakat_ 0x0a5 // "・"
#define bou_ 0x0b0 // "ー"
#define yazi_ 0x08c // "▼"
*/
#endif /* __MY_FONT_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,553 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: rtcSet.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Setting.h"
// define data------------------------------------------
//#define __RTC_MINUTE_OFFSET // この定義が有効な場合はrtcOffsetは分オフセットで算出されます。また、無効な場合は秒オフセットとなります。
// RETURNボタンLCD領域
#define RETURN_BUTTON_LT_X 2
#define RETURN_BUTTON_LT_Y 21
#define RETURN_BUTTON_RB_X (RETURN_BUTTON_LT_X + 8)
#define RETURN_BUTTON_RB_Y (RETURN_BUTTON_LT_Y + 2)
// 日付データLCD領域
#define DATE_LT_X 5
#define DATE_LT_Y 10
// 時刻データLCD領域
#define TIME_LT_X (DATE_LT_X + 14)
#define TIME_LT_Y DATE_LT_Y
// RTC設定メニュー要素
#define RTC_MENU_ELEM_NUM 1
// 文字入力タッチパネル用カウンタ
#define S_UPDOWN_COUNT_MAX 16
// 数値入力タッチパネル用カウンタ
#define D_DOWN_COUNT_MAX -50
#define D_UP_COUNT_MAX 50
// 日付時刻入力シーケンス用ワーク
typedef struct DateTimeParam {
int seq; // シーケンス番号
int *tgtp; // 入力対象の変数へのポインタ
RTCDate Date;
RTCTime Time;
}DateTimeParam;
// RTC設定シーケンス用ワーク
typedef struct SetRtcWork {
int csr; // カーソル位置
s64 rtcOffset[2]; // RTCオフセット値[0]:設定変更前の値、[1]:変更後の値)
DateTimeParam dtp; // 日付時刻入力シーケンス用ワーク
InputNumParam inp; // 数値入力インターフェース用ワーク
}SetRtcWork;
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_RtcSet_init(void);
int SEQ_RtcSet(void);
RTCWeek CalcWeekFromDate( u32 year, u32 month, u32 day );
void InputDecimal(int *tgtp, InputNumParam *inpp);
static void SEQ_InputRtcDateTime_init(int start);
static int SEQ_InputRtcDateTime(void);
static void TransmitRtcData(DateTimeParam *dtpp, RtcDateTime *rtcp);
static void SelectString( int *tgtp, const u8 **const strpp, InputNumParam *inpp);
static void BcdToHex(int *bcdp);
static void HexToBcd(int *hexp);
static BOOL CheckLeapYear( u32 year );
// global variable -------------------------------------
// static variable -------------------------------------
SetRtcWork *pRtcWork; // RTC設定用ワーク
// const data -----------------------------------------
//======================================================
// 日付&時刻設定
//======================================================
// RTC設定シーケンスの初期化
void SEQ_RtcSet_init(void)
{
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
MI_CpuClearFast(bgBakS, sizeof(bgBakS));
SVC_CpuClearFast(0xc0, oamBakS, sizeof(oamBakS));
ClearAllStringSJIS();
(void)DrawStringSJIS( 1, 0, YELLOW, (const u8 *)"DATE & TIME SET");
(void)DrawStringSJIS( DATE_LT_X + 3, DATE_LT_Y, WHITE, (const u8 *)"/ / [ ] : :");
(void)DrawStringSJIS( RETURN_BUTTON_LT_X, RETURN_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" RETURN ");
if( initialSet ) {
if( GetSYSMWork()->rtcStatus & 0x01) {
(void)DrawStringSJIS( 8, 18, RED, (const u8 *)"RTC reset is detected!");
}else {
(void)DrawStringSJIS( 8, 18, RED, (const u8 *)"Set RTC.");
}
}
pRtcWork=OS_Alloc(sizeof(SetRtcWork)); // RTC設定用ワークの確保
#ifdef __SYSM_DEBUG
if(pRtcWork==NULL) OS_Panic("ARM9- Fail to allocate memory...\n");
#endif /* __SYSM_DEBUG */
OS_Printf("Alloc :SetRtcWork\n");
SVC_CpuClear(0x0000, pRtcWork, sizeof(SetRtcWork), 16);
SVC_CpuClear(0x0000, &tpd, sizeof(TpWork), 16);
InitGetAndDrawRtcData( DATE_LT_X, DATE_LT_Y, TIME_LT_X, TIME_LT_Y); // RTCデータ表示位置の指定
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
/* if(0){
s64 offset;
RTCDate date;
RTCTime time;
date.year = 99;
date.month = 12;
date.day = 31;
time.hour = 23;
time.minute = 59;
time.second = 0;
offset = IPL2i_CalcRtcSecOffset( &date, &time ); // 設定直前のRTC値のオフセットを算出
OS_Printf( " 99/12/31 23:59:00 offset = %x\n", offset );
date.year = 100;
date.month = 1;
date.day = 1;
time.hour = 0;
time.minute = 0;
time.second = 0;
offset = IPL2i_CalcRtcSecOffset( &date, &time ); // 設定直前のRTC値のオフセットを算出
OS_Printf( "100/01/01 00:00:00 offset = %x\n", offset );
}
*/
}
// RTC設定シーケンス
int SEQ_RtcSet(void)
{
BOOL tp_set = FALSE;
BOOL tp_return = FALSE;
ReadTpData(); // タッチパネル入力の取得
GetAndDrawRtcData();
if(tpd.disp.touch) {
tp_set = InRangeTp( DATE_LT_X*8, DATE_LT_Y*8-4, // [RTC設定]領域押下チェック
(TIME_LT_X + 8)*8, (TIME_LT_Y+2)*8-4, &tpd.disp);
// [RETURN]ボタン押下チェック
tp_return = InRangeTp(RETURN_BUTTON_LT_X*8, RETURN_BUTTON_LT_Y*8-4,
RETURN_BUTTON_RB_X*8, RETURN_BUTTON_RB_Y*8-4, &tpd.disp);
}
if( initialSet && !GetNCDWork()->option.input_rtc ) {
tp_set = TRUE;
}
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & PAD_KEY_DOWN){ // カーソルの移動
if(++pRtcWork->csr == RTC_MENU_ELEM_NUM) pRtcWork->csr = 0;
}
if(pad.trg & PAD_KEY_UP){
if(--pRtcWork->csr < 0) pRtcWork->csr = RTC_MENU_ELEM_NUM - 1;
}
if((pad.trg & PAD_BUTTON_A) || (tp_set)) { // RTC設定開始
if(pRtcWork->csr == 0) {
SEQ_InputRtcDateTime_init(1);
nowProcess = SEQ_InputRtcDateTime;
}
}else if((pad.trg & PAD_BUTTON_B) || (tp_return)) { // メニューに戻る
OS_Free(pRtcWork); // RTC設定用ワークの解放
pRtcWork = NULL;
OS_Printf("Free :SetRtcWork\n");
SEQ_MainMenu_init();
}
#ifdef __SYSM_DEBUG
if(pad.trg & PAD_BUTTON_START) {
ClearRTC();
OS_Printf("RTC offset in NVRAM is ZERO clear!\n");
}
#endif /* __SYSM_DEBUG */
return 0;
}
//======================================================
// 日付&時刻入力処理
//======================================================
// 日付時刻入力初期化
static void SEQ_InputRtcDateTime_init(int start)
{
mf_clearRect( RETURN_BUTTON_LT_X, RETURN_BUTTON_LT_Y, 2, 28);
if(start) {
DrawOKCancelButton();
pRtcWork->dtp.seq = 0;
}else {
(void)DrawStringSJIS( RETURN_BUTTON_LT_X, RETURN_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" RETURN ");
}
SVC_CpuClear(0x0000, &tpd, sizeof(TpWork), 16);
}
// 日付時刻入力
static int SEQ_InputRtcDateTime(void)
{
BOOL tp_ok = FALSE;
BOOL tp_cancel = FALSE;
int new_seq, x_base, y_base, abs_y_offset;
enum { // 日付時刻入力シーケンス番号
SEQ_INIT=0,
SEQ_YEAR_INIT=2, SEQ_YEAR_SET,
SEQ_MONTH_INIT, SEQ_MONTH_SET,
SEQ_DAY_INIT, SEQ_DAY_SET,
SEQ_HOUR_INIT, SEQ_HOUR_SET,
SEQ_MINUTE_INIT, SEQ_MINUTE_SET,
SEQ_SECOND_INIT, SEQ_SECOND_SET,
SEQ_END,
SEQ_RETURN=64
};
ReadTpData(); // タッチパネル入力の取得
CheckOKCancelButton(&tp_ok, &tp_cancel); // [OK],[CANCEL]ボタン押下チェック
pRtcWork->inp.y_offset = 0;
if(tpd.disp.touch) { // [CANCEL]ボタン押下チェック
if((pRtcWork->dtp.seq & 0x01) && (pRtcWork->dtp.seq < SEQ_END)) { // SEQ_**_SETの時のみ有効
new_seq = pRtcWork->dtp.seq;
x_base = DATE_LT_X * 8;
y_base = DATE_LT_Y * 8 + 6;
// 入力項目移動のチェック
if( InRangeTp( x_base, (y_base - 6), (x_base + 22 * 8), (y_base + 6), &tpd.disp) ) {
if(tpd.disp.x < x_base + 28) {
new_seq = SEQ_YEAR_SET;
}else if((tpd.disp.x >= x_base + 4*8) && (tpd.disp.x < x_base + 6*8)) {
new_seq = SEQ_MONTH_SET;
}else if((tpd.disp.x >= x_base + 7*8) && (tpd.disp.x < x_base + 9*8)) {
new_seq = SEQ_DAY_SET;
}else if((tpd.disp.x >= x_base + 14*8) && (tpd.disp.x < x_base + 16*8)) {
new_seq = SEQ_HOUR_SET;
}else if((tpd.disp.x >= x_base + 17*8) && (tpd.disp.x < x_base + 19*8)) {
new_seq = SEQ_MINUTE_SET;
}else if(tpd.disp.x >= x_base + 20*8) {
new_seq = SEQ_SECOND_SET;
}
}
if(pRtcWork->dtp.seq != new_seq) {
pRtcWork->dtp.seq = new_seq - 1;
}else {
// 入力値の増減
if(InRangeTp( pRtcWork->inp.pos_x * 8, (y_base - 30), (pRtcWork->inp.pos_x + pRtcWork->inp.keta_max)*8, (y_base + 30), &tpd.disp)) {
pRtcWork->inp.y_offset = tpd.disp.y - y_base;
abs_y_offset = (pRtcWork->inp.y_offset >= 0) ? pRtcWork->inp.y_offset : -pRtcWork->inp.y_offset;
if(abs_y_offset <= 6) {
pRtcWork->inp.y_offset = 0;
}else if(abs_y_offset <= 14){
pRtcWork->inp.y_offset >>= 2;
}else if(abs_y_offset <= 22){
pRtcWork->inp.y_offset >>= 1;
}
}
}
}
}
// タッチパネル or キー入力によって、カーソル位置が動いた時に、元の位置のカーソルを消す。
if((pRtcWork->dtp.seq > 0) && ((pRtcWork->dtp.seq & 0x01) == 0)) { // SEQ_INITの時は実行しない
(void)DrawDecimalSJIS( pRtcWork->inp.pos_x, pRtcWork->inp.pos_y, WHITE, pRtcWork->dtp.tgtp, (u8)pRtcWork->inp.keta_max, 4);
}
// 各シーケンスの処理
switch(pRtcWork->dtp.seq){
case SEQ_INIT:
pRtcWork->dtp.Date = GetSYSMWork()->rtc[0].Date;
pRtcWork->dtp.Time = GetSYSMWork()->rtc[0].Time;
pRtcWork->dtp.Date.year += 2000; // yearをする。
pRtcWork->dtp.seq = SEQ_YEAR_INIT;
// ※SEQ_INITは直通でSEQ_YEAR_INITへ
case SEQ_YEAR_INIT:
pRtcWork->inp.pos_x = DATE_LT_X;
pRtcWork->inp.pos_y = DATE_LT_Y;
pRtcWork->inp.keta_max = 4;
pRtcWork->inp.value_max = 2099;
pRtcWork->inp.value_min = 2000;
// pRtcWork->inp.value_min = 2004;
// if(pRtcWork->dtp.Date.year < 2004) {
// pRtcWork->dtp.Date.year = 2004;
// }
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Date.year;
break;
case SEQ_MONTH_INIT:
pRtcWork->inp.pos_x = DATE_LT_X + 4;
pRtcWork->inp.keta_max = 2;
pRtcWork->inp.value_max = 12;
pRtcWork->inp.value_min = 1;
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Date.month;
break;
case SEQ_DAY_INIT:
pRtcWork->inp.pos_x = DATE_LT_X + 7;
pRtcWork->inp.keta_max = 2;
pRtcWork->inp.value_max = (int)SYSM_GetDayNum( pRtcWork->dtp.Date.year, pRtcWork->dtp.Date.month );
// 年・月をもとにその月の日数を算出する。
pRtcWork->inp.value_min = 1;
if(pRtcWork->dtp.Date.day > pRtcWork->inp.value_max) {
pRtcWork->dtp.Date.day = (u32)pRtcWork->inp.value_max;
}
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Date.day;
break;
case SEQ_HOUR_INIT:
pRtcWork->inp.pos_x = TIME_LT_X;
pRtcWork->inp.keta_max = 2;
pRtcWork->inp.value_max = 23;
pRtcWork->inp.value_min = 0;
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Time.hour;
break;
case SEQ_MINUTE_INIT:
pRtcWork->inp.pos_x = TIME_LT_X + 3;
pRtcWork->inp.keta_max = 2;
pRtcWork->inp.value_max = 59;
pRtcWork->inp.value_min = 0;
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Time.minute;
break;
case SEQ_SECOND_INIT:
pRtcWork->inp.pos_x = TIME_LT_X + 6;
pRtcWork->inp.keta_max = 2;
pRtcWork->inp.value_max = 59;
pRtcWork->inp.value_min = 0;
pRtcWork->dtp.tgtp = (int *)&pRtcWork->dtp.Time.second;
break;
case SEQ_YEAR_SET:
case SEQ_MONTH_SET:
case SEQ_DAY_SET:
case SEQ_HOUR_SET:
case SEQ_MINUTE_SET:
case SEQ_SECOND_SET:
InputDecimal( pRtcWork->dtp.tgtp, &pRtcWork->inp);
// 年月日入力ならば、曜日を算出して表示。
if( (pRtcWork->dtp.seq == SEQ_YEAR_SET) || (pRtcWork->dtp.seq == SEQ_MONTH_SET) || (pRtcWork->dtp.seq == SEQ_DAY_SET) ) {
pRtcWork->dtp.Date.week = CalcWeekFromDate(pRtcWork->dtp.Date.year, pRtcWork->dtp.Date.month, pRtcWork->dtp.Date.day);
(void)DrawStringSJIS( DATE_LT_X + 10, DATE_LT_Y, WHITE, g_strWeek[pRtcWork->dtp.Date.week]);
}
// 年・月入力ならば、日数を算出して、現在の入力日が日数を超えていたら修正する。
if( (pRtcWork->dtp.seq == SEQ_YEAR_SET) || (pRtcWork->dtp.seq == SEQ_MONTH_SET) ) {
u32 dayNum = SYSM_GetDayNum( pRtcWork->dtp.Date.year, pRtcWork->dtp.Date.month );
if( dayNum < pRtcWork->dtp.Date.day) {
pRtcWork->dtp.Date.day = dayNum;
(void)DrawDecimalSJIS( DATE_LT_X + 7, DATE_LT_Y, WHITE, &pRtcWork->dtp.Date.day, 2, 4);
}
}
break;
case SEQ_END:
pRtcWork->dtp.Date.year -= 2000; // yearをする。
/* // RTCへの新しい値の設定
(void)RTC_GetDateTime(&now_dtp.Date, &now_dtp.Time); // ライト直前に現在のRTC値を取得する。
(void)RTC_SetDateTime(&pRtcWork->dtp.Date, &pRtcWork->dtp.Time); // 新RTC設定値のセット。
if((GetSYSMWork()->rtc[0].Date.year == 99) && (now_dtp.Date.year == 0)) {
now_dtp.Date.year = 100; // 設定前設定完了の間にRTCが一周してしまったら、yearは100としてoffsetを計算する。
}
// RTC設定時は、今回の設定でどれだけRTC値が変化したか秒オフセット単位を算出してNVRAMに保存する。とりあえず実装
pRtcWork->rtcOffset[0] = IPL2i_CalcRtcSecOffset( &now_dtp.Date, &now_dtp.Time ); // 現在のRTC値のオフセットを算出
pRtcWork->rtcOffset[1] = IPL2i_CalcRtcSecOffset( &pRtcWork->dtp.Date, &pRtcWork->dtp.Time ); // 新しくセットされたRTC値のオフセットを算出
GetNCDWork()->option.rtcOffset += pRtcWork->rtcOffset[1] - pRtcWork->rtcOffset[0];
// 新RTC_ofs と 現在のRTC_ofs の差分の値を加算。
*/
pRtcWork->dtp.Time.second = 0;
NCD_SetRtcOffset( SYSM_CalcRtcOffsetAndSetDateTime( &pRtcWork->dtp.Date, &pRtcWork->dtp.Time ) );
GetSYSMWork()->rtc[0].Date = pRtcWork->dtp.Date;
GetSYSMWork()->rtc[0].Time = pRtcWork->dtp.Time;
GetSYSMWork()->ncd_invalid = 0;
GetNCDWork()->option.input_rtc = 1; // RTC入力フラグを立てる。
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData (GetNCDWork());
// SEQ_ENDの時はこのままリターンする。
case SEQ_RETURN:
nowProcess = SEQ_RtcSet;
SEQ_InputRtcDateTime_init(0); // 日付入力画面のクリア
return 0;
}
if(pRtcWork->dtp.seq & 0x01) { // SEQ_**_SETの時のみ有効
if((pad.trg & PAD_BUTTON_A) || (tp_ok)) {
pRtcWork->dtp.seq = SEQ_END; // Aボタンで決定
}else if((pad.trg & PAD_BUTTON_B) || (tp_cancel)) { // Bボタンでキャンセル
pRtcWork->dtp.seq = SEQ_RETURN;
}else if(pad.trg & PAD_KEY_LEFT) {
if(pRtcWork->dtp.seq == SEQ_YEAR_SET) pRtcWork->dtp.seq = SEQ_SECOND_INIT;
else pRtcWork->dtp.seq -= 3;
}else if(pad.trg & PAD_KEY_RIGHT) {
if(pRtcWork->dtp.seq == SEQ_SECOND_SET) pRtcWork->dtp.seq = SEQ_YEAR_INIT;
else pRtcWork->dtp.seq++;
}
}else { // SEQ_**_INITの時のみ有効
pRtcWork->dtp.seq++;
}
return 0;
}
/*
// うるう年の判定 (うるう年:1、通常の年:0リターン)
BOOL CheckLeapYear( u32 year)
{
if((year & 0x03) == 0) { // うるう年は、「4で割り切れ かつ 100で割り切れない年」
CP_SetDiv32_32(year, 100); // 「400で割り切れる年」
if(CP_GetDivRemainder32() != 0) {
return TRUE;
}else {
CP_SetDiv32_32(year, 400);
if(CP_GetDivRemainder32() == 0) {
return TRUE;
}
}
}
return FALSE;
}
*/
// 日付から曜日を求める。
RTCWeek CalcWeekFromDate( u32 year, u32 month, u32 day )
{
if(month == 1 || month == 2 ){
year--;
month += 12;
}
return (RTCWeek)( (year + year/4 - year/100 + year/400 + (13*month + 8)/5 + day) % 7 );
}
/*
// 文字列によるパラメータ選択
static void SelectString(int *tgtp, const u8 **const srtpp, InputNumParam *inpp)
{
BOOL value_up = FALSE;
BOOL value_down = FALSE;
if(inpp->y_offset == 0) {
inpp->up_count = S_UPDOWN_COUNT_MAX;
}else {
inpp->up_count ++;
if(inpp->up_count > S_UPDOWN_COUNT_MAX) {
inpp->up_count = 0;
if(inpp->y_offset < 0) value_up = TRUE;
else value_down = TRUE;
}
}
if((pad.trg & PAD_KEY_DOWN) || (value_down)) { // 表示文字列切り替え
if(++*tgtp>inpp->value_max) *tgtp = 0;
}else if((pad.trg & PAD_KEY_UP) || (value_up)) {
if(--*tgtp & 0x8000) *tgtp = inpp->value_max;
}
(void)DrawStringSJIS( inpp->pos_x, inpp->pos_y, HIGHLIGHT_Y, srtpp[*tgtp]); // 現在選択している文字列を表示
}
*/
// 10進数数値入力
void InputDecimal(int *tgtp, InputNumParam *inpp)
{
BOOL value_up = FALSE;
BOOL value_down = FALSE;
if(inpp->y_offset == 0) {
inpp->up_count = D_UP_COUNT_MAX;
inpp->down_count = D_DOWN_COUNT_MAX;
}else if(inpp->y_offset < 0) {
inpp->down_count += inpp->y_offset;
if(inpp->down_count < D_DOWN_COUNT_MAX) {
inpp->down_count = 0;
value_down = TRUE;
}
}else { // y_offset > 0
inpp->up_count += inpp->y_offset;
if(inpp->up_count > D_UP_COUNT_MAX) {
inpp->up_count = 0;
value_up = TRUE;
}
}
// キー入力に応じて対象値を増減
if( (value_down) || (pad.trg & PAD_KEY_UP)
|| ((pad.cont & PAD_KEY_UP) && (pad.cont & PAD_BUTTON_R)) ) {
if(--*tgtp < inpp->value_min) {
*tgtp = inpp->value_max;
}
}else if( (value_up) || (pad.trg & PAD_KEY_DOWN)
|| ((pad.cont & PAD_KEY_DOWN) && (pad.cont & PAD_BUTTON_R)) ) {
if(++*tgtp > inpp->value_max) {
*tgtp = inpp->value_min;
}
}
(void)DrawDecimalSJIS( inpp->pos_x, inpp->pos_y, HIGHLIGHT_Y, tgtp, (u8)inpp->keta_max, 4);
// 対象値をハイライト表示
}
// RTC設定のクリア
void ClearRTC( void )
{
SVC_CpuClear(0x0000, &GetSYSMWork()->rtc[0].Time, sizeof(RTCTime), 16);
GetSYSMWork()->rtc[0].Date.year = 0;
GetSYSMWork()->rtc[0].Date.month = 1;
GetSYSMWork()->rtc[0].Date.day = 1;
(void)RTC_SetDateTime( &GetSYSMWork()->rtc[0].Date, &GetSYSMWork()->rtc[0].Time);
GetNCDWork()->option.input_rtc = 0;
GetNCDWork()->option.rtcOffset = 0;
NCD_SetRtcLastSetYear( 0 );
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData (GetNCDWork());
}

View File

@ -0,0 +1,308 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: mainMenu.c
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.h>
#include "main.h"
#include "DS_Setting.h"
#include "spi.h"
// define data------------------------------------------
// キャンセルボタンLCD領域
#define CANCEL_BUTTON_LT_X 12
#define CANCEL_BUTTON_LT_Y 21
#define CANCEL_BUTTON_RB_X (CANCEL_BUTTON_LT_X + 8)
#define CANCEL_BUTTON_RB_Y (CANCEL_BUTTON_LT_Y + 2)
// OKボタンLCD領域
#define OK_BUTTON_LT_X 22
#define OK_BUTTON_LT_Y 21
#define OK_BUTTON_RB_X (OK_BUTTON_LT_X + 8)
#define OK_BUTTON_RB_Y (OK_BUTTON_LT_Y + 2)
#define MAIN_MENU_ELEM_NUM 6 // メインメニューの項目数
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_MainMenu_init(void);
int SEQ_MainMenu(void);
BOOL SelectMenuByTp(u16 *nowCsr, const MenuComponent *menu);
//BOOL InRangeTp(u16 lt_x,u16 lt_y,u16 rb_x,u16 rb_y, TPData *tgt);
BOOL InRangeTp(int lt_x, int lt_y, int rb_x, int rb_y, TPData *tgt);
static void SEQ_SettingEnd_init( void );
static int SEQ_SettingEnd( void );
// global variable -------------------------------------
u16 csrMenu = 0; // メニューのカーソル位置bm_main.cで参照してるので、グローバル
BOOL initialSet = FALSE;
// static variable -------------------------------------
static const u8 *str_MainMenu[MAIN_MENU_ELEM_NUM]; // メインメニュー用文字テーブルへのポインタリスト
// const data -----------------------------------------
//===============================================
// mainMenu.c
//===============================================
const u8 *const str_MeinMenuElemTbl[ MAIN_MENU_ELEM_NUM ][ LANG_CODE_MAX ] = {
{
(const u8 *)"ユーザー じょうほう   ",
(const u8 *)"USER INFORMATION ",
(const u8 *)"USER INFORMATION(F)",
(const u8 *)"USER INFORMATION(G)",
(const u8 *)"USER INFORMATION(I)",
(const u8 *)"USER INFORMATION(S)",
},
{
(const u8 *)"ひづけ & じこく    ",
(const u8 *)"DATE & TIME ",
(const u8 *)"DATE & TIME(F) ",
(const u8 *)"DATE & TIME(G) ",
(const u8 *)"DATE & TIME(I) ",
(const u8 *)"DATE & TIME(S) ",
},
{
(const u8 *)"げんご          ",
(const u8 *)"LANGUAGE ",
(const u8 *)"LANGUAGE(F) ",
(const u8 *)"LANGUAGE(G) ",
(const u8 *)"LANGUAGE(I) ",
(const u8 *)"LANGUAGE(S) ",
},
{
(const u8 *)"AGB モード        ",
(const u8 *)"AGB MODE ",
(const u8 *)"AGB MODE(F) ",
(const u8 *)"AGB MODE(G) ",
(const u8 *)"AGB MODE(I) ",
(const u8 *)"AGB MODE(S) ",
},
{
(const u8 *)"タッチパネルほせい     ",
(const u8 *)"TOUCH PANEL ",
(const u8 *)"TOUCH PANEL(F) ",
(const u8 *)"TOUCH PANEL(G) ",
(const u8 *)"TOUCH PANEL(I) ",
(const u8 *)"TOUCH PANEL(S) ",
},
{
(const u8 *)"きどうモード        ",
(const u8 *)"AUTO BOOT ",
(const u8 *)"AUTO BOOT(F) ",
(const u8 *)"AUTO BOOT(G) ",
(const u8 *)"AUTO BOOT(I) ",
(const u8 *)"AUTO BOOT(S) ",
},
};
const MenuComponent mainMenu = {
MAIN_MENU_ELEM_NUM,
2,
6,
0,
2,
17,
WHITE,
HIGHLIGHT_Y,
(const u8 **)&str_MainMenu,
};
//======================================================
// メインメニュー
//======================================================
// メインメニューの初期化
void SEQ_MainMenu_init(void)
{
#ifdef __DIRECT_BOOT_BMENU_ENABLE
// 各種設定が未設定時のダイレクト起動。
{
if(GetNCDWork()->option.input_language == 0) { // 言語設定がまだ。
initialSet = TRUE;
csrMenu = 3;
SEQ_LangSelect_init();
nowProcess = SEQ_LangSelect;
return;
}else if(GetNCDWork()->option.input_tp == 0) { // TPキャリブレーションがまだ。
initialSet = TRUE;
csrMenu = 5;
SEQ_TP_Calibration_init();
nowProcess = SEQ_TP_Calibration;
return ;
}else if(GetNCDWork()->option.input_rtc == 0) { // RTC設定がまだ。
ClearRTC();
initialSet = TRUE;
csrMenu = 2;
SEQ_RtcSet_init();
nowProcess = SEQ_RtcSet;
return;
}else if( (GetNCDWork()->option.input_nickname == 0) // ニックネームまたは好きな色入力がまだ。
|| (GetNCDWork()->option.input_favoriteColor == 0) ) {
initialSet = TRUE;
csrMenu = 1;
SEQ_OwnerInfo_init();
nowProcess = SEQ_OwnerInfo;
return;
}
if( initialSet ) {
SEQ_SettingEnd_init();
nowProcess = SEQ_SettingEnd;
return;
}
}
#endif /* __DIRECT_BOOT_BMENU_ENABLE */
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
SVC_CpuClearFast(0x0000, bgBakS, sizeof(bgBakS));
SVC_CpuClearFast(0xc0, oamBakS, sizeof(oamBakS));
ClearAllStringSJIS();
#ifdef __NCD_CLEAR_ENABLE
(void)DrawStringSJIS( 18, 21, LIGHTGREEN, (const u8 *)"[START]:NCD clear.");
#endif /* __NCD_CLEAR_ENABLE */
// NITRO設定データのlanguageに応じたメインメニュー構成言語の切り替え
{
int i;
NvLangCode langCode = LANG_ENGLISH;
if(GetSYSMWork()->ncd_invalid == 0) {
langCode = (NvLangCode)GetNCDWork()->option.language;
}
for(i = 0; i < MAIN_MENU_ELEM_NUM; i++) {
str_MainMenu[i] = str_MeinMenuElemTbl[i][langCode];
}
}
DrawMenu(csrMenu, &mainMenu);
SVC_CpuClear(0x0000,&tpd,sizeof(TpWork),16);
GXS_SetVisiblePlane(GX_PLANEMASK_BG1);
nowProcess = SEQ_MainMenu;
}
// メインメニュー
int SEQ_MainMenu(void)
{
BOOL tp_select;
ReadTpData(); // タッチパネル入力の取得
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & PAD_KEY_DOWN){ // カーソルの移動
if(++csrMenu == MAIN_MENU_ELEM_NUM) csrMenu=0;
}
if(pad.trg & PAD_KEY_UP){
if(--csrMenu & 0x80) csrMenu=MAIN_MENU_ELEM_NUM-1;
}
tp_select=SelectMenuByTp(&csrMenu, &mainMenu);
DrawMenu(csrMenu, &mainMenu);
if((pad.trg & PAD_BUTTON_A)||(tp_select)) { // メニュー項目への分岐
switch(csrMenu) {
case 0:
SEQ_OwnerInfo_init();
nowProcess=SEQ_OwnerInfo;
break;
case 1:
SEQ_RtcSet_init();
nowProcess=SEQ_RtcSet;
break;
case 2:
SEQ_LangSelect_init();
nowProcess=SEQ_LangSelect;
break;
case 3:
SEQ_AgbLcdSelect_init();
nowProcess=SEQ_AgbLcdSelect;
break;
case 4:
SEQ_TP_Calibration_init();
nowProcess=SEQ_TP_Calibration;
break;
case 5:
SEQ_AutoBootSelect_init();
nowProcess=SEQ_AutoBootSelect;
break;
}
}
#ifdef __NCD_CLEAR_ENABLE
if(pad.trg & PAD_BUTTON_START) {
SVC_CpuClearFast(0x0000, GetNCDWork(), sizeof(NitroConfigData));
(void)SPI_NvramWriteEnable();
SVC_WaitVBlankIntr();
(void)SPI_NvramPageErase(0x3fe00);
SVC_WaitVBlankIntr();
(void)SPI_NvramWriteEnable();
SVC_WaitVBlankIntr();
(void)SPI_NvramPageErase(0x3ff00);
SVC_WaitVBlankIntr();
(void)SPI_NvramWriteDisable();
OS_Printf("NitroConfigData zero clear!!\n");
}
#endif /* __NCD_CLEAR_ENABLE */
return 0;
}
// OK / CANCELボタンの描画
void DrawOKCancelButton(void)
{
(void)DrawStringSJIS( CANCEL_BUTTON_LT_X, CANCEL_BUTTON_LT_Y,HIGHLIGHT_C, (const u8 *)" CANCEL ");
(void)DrawStringSJIS( OK_BUTTON_LT_X, OK_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" OK ");
}
// OK or CANCELボタン押下チェック
void CheckOKCancelButton(BOOL *tp_ok, BOOL *tp_cancel)
{
*tp_cancel = InRangeTp(CANCEL_BUTTON_LT_X*8, CANCEL_BUTTON_LT_Y*8-4,
CANCEL_BUTTON_RB_X*8, CANCEL_BUTTON_RB_Y*8-4, &tpd.disp);
*tp_ok = InRangeTp(OK_BUTTON_LT_X*8, OK_BUTTON_LT_Y*8-4,
OK_BUTTON_RB_X*8, OK_BUTTON_RB_Y*8-4, &tpd.disp);
}
//---------------------------------------------------------
//
// 設定終了
//
//---------------------------------------------------------
static void SEQ_SettingEnd_init( void )
{
ClearAllStringSJIS();
(void)DrawStringSJIS( 6, 10, WHITE, (const u8 *)" Initial setting completed.");
(void)DrawStringSJIS( 6, 12, WHITE, (const u8 *)" Please reboot.");
}
static int SEQ_SettingEnd( void )
{
return 0;
}

View File

@ -0,0 +1,516 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: tpCalib.c
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.h>
#include <sysmenu.h>
#include "misc.h"
#include "DS_Setting.h"
// define data------------------------------------------
// OKボタンLCD領域
#define OK_BUTTON_LT_X 2
#define OK_BUTTON_LT_Y 20
#define OK_BUTTON_RB_X (OK_BUTTON_LT_X + 8)
#define OK_BUTTON_RB_Y (OK_BUTTON_LT_Y + 2)
// キャンセルボタンLCD領域
#define CANCEL_BUTTON_LT_X 11
#define CANCEL_BUTTON_LT_Y 20
#define CANCEL_BUTTON_RB_X (CANCEL_BUTTON_LT_X+8)
#define CANCEL_BUTTON_RB_Y (CANCEL_BUTTON_LT_Y+2)
// リトライボタンLCD領域
#define RETRY_BUTTON_LT_X 20
#define RETRY_BUTTON_LT_Y 20
#define RETRY_BUTTON_RB_X (RETRY_BUTTON_LT_X+8)
#define RETRY_BUTTON_RB_Y (RETRY_BUTTON_LT_Y+2)
// キャリブレーション用OBJデータ
const u16 bitmapOBJPoint[8 * 8 * 5];
// 各種キャラクタデータサイズ
#define IMAGE_DATA (bitmapOBJPoint)
#define IMAGE_DATA_SIZE (sizeof(bitmapOBJPoint))
#define MY_CHAR_SIZE (sizeof(myChar))
// NITRO-LCDサイズ
#define DISP_X_SIZE 256
#define DISP_Y_SIZE 192
// キャリブレーションシーケンス番号CalibWork.seqの値
enum {
SEQ_INIT=0, SEQ_INTERVAL_0,
SEQ_CALIBRATE_1, SEQ_INTERVAL_1,
SEQ_CALIBRATE_2, SEQ_INTERVAL_2,
SEQ_CHECK_PARAM, SEQ_INTERVAL_3,
SEQ_GET_POINT
};
// キャリブレーション設定ワーク
typedef struct CalibWork {
u32 seq;
u16 release_count;
u16 touch_count;
u16 last_x;
u16 last_y;
TPData sample[2];
TPCalibrateParam calibrate;
}CalibWork;
// extern data------------------------------------------
// function's prototype declaration---------------------
void SEQ_TP_Calibration_init(void);
int SEQ_TP_Calibration(void);
static void DisplayInit();
static BOOL GetSamplePointNow(TPData *data);
static BOOL WaitPanelReleaseNow( void );
static void ReturnMenu(void);
// global variable -------------------------------------
// static variable -------------------------------------
static CalibWork *cw;
// const data -----------------------------------------
//======================================================
// function's description
//======================================================
/*---------------------------------------------------------------------------*
Name: SetPoint8x8
Description: Display a 8x8 OBJ on indicated point.
Arguments: x - position X.
y - position Y.
Returns: None.
*---------------------------------------------------------------------------*/
static inline void SetPoint8x8(u16 pos_x, u16 pos_y)
{
G2_SetOBJAttr( &oamBakS[0], // OAM number
pos_x - 4, // X position
pos_y - 4, // Y position
0, // Priority
GX_OAM_MODE_BITMAPOBJ, // Bitmap mode
FALSE, // mosaic off
GX_OAM_EFFECT_NONE, // affine off
GX_OAM_SHAPE_8x8, // 8x8 size
GX_OAM_COLOR_16, // 16 color
0x60, // charactor
15, // alpha
0);
}
/*---------------------------------------------------------------------------*
Name: SetPoint16x16
Description: Display a 16x16 OBJ on indicated point.
Arguments: x - position X.
y - position Y.
Returns: None.
*---------------------------------------------------------------------------*/
static inline void SetPoint16x16(u16 pos_x, u16 pos_y)
{
G2_SetOBJAttr( &oamBakS[0], // OAM number
pos_x - 8, // X position
pos_y - 8, // Y position
0, // Priority
GX_OAM_MODE_BITMAPOBJ, // Bitmap mode
FALSE, // mosaic off
GX_OAM_EFFECT_NONE, // affine off
GX_OAM_SHAPE_16x16, // 16x16 size
GX_OAM_COLOR_16, // 16 color
0x61, // charactor
15, // alpha
0);
}
/*---------------------------------------------------------------------------*
Name: DisplayInit
Description: Graphics Initialization
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
static void DisplayInit()
{
GXS_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K); // 2D mapping OBJ
/* Load charactor bitmap data */
GXS_LoadOBJ( (const void *)IMAGE_DATA, 0x3000 /* 0 */, IMAGE_DATA_SIZE ); // Transfer OBJ bitmap data to VRAM
}
/*---------------------------------------------------------------------------*
Name: GetSamplePointNow
Description: Get touched point by OneTime Sampling.
This function use TP_RequestSampling() and TP_WaitRawResult()
Arguments: None.
Returns: data - getton TouchPanel data.
BOOL - if touched and got point this function returns TRUE.
else FALSE.
*---------------------------------------------------------------------------*/
static BOOL GetSamplePointNow(TPData *data)
{
TPData temp;
enum {
OK_COUNT = 4, OK_RANGE = 50
};
// Detect a point pushed during definite time.
while (TP_RequestRawSampling( &temp )) { };
if (! temp.touch ) {
cw->touch_count = 0;
return FALSE;
}
if ( temp.validity != TP_VALIDITY_VALID ) {
cw->touch_count = 0;
return FALSE;
}
OS_Printf("( %d, %d )\n", temp.x, temp.y);
cw->touch_count++;
if ( cw->touch_count == 1 ) {
cw->last_x = temp.x;
cw->last_y = temp.y;
return FALSE;
}
// if jump point from last frame, reset count.
if ( (s32)(cw->last_x - temp.x) < - OK_RANGE ||
(s32)(cw->last_x - temp.x) > OK_RANGE )
{
cw->touch_count = 1;
cw->last_x = temp.x;
cw->last_y = temp.y;
return FALSE;
}
if ( (s32)(cw->last_y - temp.y) < - OK_RANGE ||
(s32)(cw->last_y - temp.y) > OK_RANGE )
{
cw->touch_count = 1;
cw->last_x = temp.x;
cw->last_y = temp.y;
return FALSE;
}
// if the point pressed during OK_COUNT, detect finish.
if ( cw->touch_count == OK_COUNT ) {
data->x = (u16) ( (temp.x + cw->last_x) / 2 );
data->y = (u16) ( (temp.y + cw->last_y) / 2 );
data->touch = TP_TOUCH_ON;
data->validity = TP_VALIDITY_VALID;
cw->touch_count=0;
return TRUE;
}
cw->last_x = temp.x;
cw->last_y = temp.y;
return FALSE;
}
/*---------------------------------------------------------------------------*
Name: WaitPanelReleaseNow
Description: Wait to released TouchPanel, using OneTime Sampling.
This function is using TP_RequestSampling() and TP_WaitRawResult().
Arguments: None.
Returns: BOOL - if TouchPanel is released , this returns TRUE.
else FALSE.
*---------------------------------------------------------------------------*/
static BOOL WaitPanelReleaseNow( void )
{
TPData temp;
enum {
INTERVAL_CNT = 10
};
while (TP_RequestRawSampling( &temp )) {
SVC_WaitByLoop(0x400);
};
if ( temp.touch ) {
cw->release_count = 0;
return FALSE;
}
cw->release_count++;
if ( cw->release_count >= INTERVAL_CNT ) {
cw->release_count = 0;
return TRUE;
} else {
return FALSE;
}
}
/*---------------------------------------------------------------------------*
Name: SEQ_TP_Calibration
Description: Initialization and main loop
Arguments: None.
Returns: None.
*---------------------------------------------------------------------------*/
int SEQ_TP_Calibration(void)
{
BOOL tp_ok = FALSE;
BOOL tp_cancel = FALSE;
BOOL tp_retry = FALSE;
switch (cw->seq) {
case SEQ_INIT:
mf_clearRect(0, 20, 4, 32);
cw->seq=SEQ_INTERVAL_0;
(void)DrawStringSJIS( 2, 21, CYAN,(const u8 *)"[B]:CANCEL");
break;
case SEQ_INTERVAL_0:
// wait release TouchPanel
if ( WaitPanelReleaseNow() ) {
cw->seq=SEQ_CALIBRATE_1;
}
break;
case SEQ_CALIBRATE_1:
// detect first point.
SetPoint8x8(32, 32);
if ( GetSamplePointNow(&cw->sample[0]) ) {
OS_Printf("OK! ( %d, %d )\n", cw->sample[0].x, cw->sample[0].y);
cw->seq = SEQ_INTERVAL_1;
}
break;
case SEQ_INTERVAL_1:
// wait release TouchPanel
if ( WaitPanelReleaseNow() ) {
cw->seq = SEQ_CALIBRATE_2;
}
break;
case SEQ_CALIBRATE_2:
// detect second point.
SetPoint8x8( DISP_X_SIZE - 32, DISP_Y_SIZE - 32 );
if ( GetSamplePointNow(&cw->sample[1]) ) {
OS_Printf("OK! ( %d, %d )\n", cw->sample[1].x, cw->sample[1].y);
// Calculate and set calibration parameter from two detected point.
(void)TP_CalcCalibrateParam( &cw->calibrate,
cw->sample[0].x, cw->sample[0].y, 32, 32,
cw->sample[1].x, cw->sample[1].y, DISP_X_SIZE - 32, DISP_Y_SIZE - 32 );
TP_SetCalibrateParam( &cw->calibrate );
OS_Printf("Calibrate param: \n");
OS_Printf("\tx = %d, xDotSize = %d\n", cw->calibrate.x0, cw->calibrate.xDotSize / 0x100);
OS_Printf("\ty = %d, yDotSize = %d\n", cw->calibrate.y0, cw->calibrate.yDotSize / 0x100);
OS_Printf("Check calibrate param\n");
cw->seq = SEQ_INTERVAL_2;
}
break;
case SEQ_INTERVAL_2:
// Wait release TouchPanel
if ( WaitPanelReleaseNow() ) {
cw->seq = SEQ_CHECK_PARAM;
}
break;
case SEQ_CHECK_PARAM:
// Verify Calibrattion Parameter.
SetPoint8x8( DISP_X_SIZE / 2, DISP_Y_SIZE / 2 );
if ( GetSamplePointNow(&tpd.raw) ) {
TP_GetUnCalibratedPoint( &tpd.disp.x, &tpd.disp.y, DISP_X_SIZE / 2, DISP_Y_SIZE / 2 );
cw->seq = SEQ_GET_POINT;
mf_clearRect( 2, 21, 2, 10);
(void)DrawStringSJIS( OK_BUTTON_LT_X, OK_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" OK ");
(void)DrawStringSJIS( CANCEL_BUTTON_LT_X, CANCEL_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" CANCEL ");
(void)DrawStringSJIS( RETRY_BUTTON_LT_X, RETRY_BUTTON_LT_Y, HIGHLIGHT_C, (const u8 *)" RETRY ");
(void)DrawStringSJIS( (u16)(OK_BUTTON_LT_X + 2), (u16)(OK_BUTTON_LT_Y + 2), CYAN,(const u8 *)"[A]");
(void)DrawStringSJIS( (u16)(CANCEL_BUTTON_LT_X + 2), (u16)(CANCEL_BUTTON_LT_Y + 2), CYAN,(const u8 *)"[B]");
(void)DrawStringSJIS( (u16)(RETRY_BUTTON_LT_X), (u16)(RETRY_BUTTON_LT_Y + 2), CYAN,(const u8 *)"[START]");
{
s32 xRange, yRange;
xRange = tpd.raw.x - tpd.disp.x;
yRange = tpd.raw.y - tpd.disp.y;
OS_Printf("OK! ( %d, %d )\n", tpd.raw.x, tpd.raw.y);
OS_Printf("Raw ( %d, %d )\n", tpd.disp.x, tpd.disp.y);
OS_Printf("\txRange = %d, yRange = %d\n", xRange, yRange);
}
}
break;
case SEQ_GET_POINT:
// Draw Marker by calibrated point.
while ( TP_RequestRawSampling( &tpd.raw ) ) {
SVC_WaitByLoop(0x400);
}
TP_GetCalibratedPoint( &tpd.disp, &tpd.raw );
if ( tpd.raw.touch ) {
SetPoint16x16( tpd.disp.x, tpd.disp.y );
// [OK] [CANCEL] [RETRY]ボタン押下チェック
tp_ok = InRangeTp(OK_BUTTON_LT_X*8, OK_BUTTON_LT_Y*8-4,
OK_BUTTON_RB_X*8, OK_BUTTON_RB_Y*8-4, &tpd.disp);
tp_cancel = InRangeTp(CANCEL_BUTTON_LT_X*8, CANCEL_BUTTON_LT_Y*8-4,
CANCEL_BUTTON_RB_X*8, CANCEL_BUTTON_RB_Y*8-4, &tpd.disp);
tp_retry = InRangeTp(RETRY_BUTTON_LT_X*8, RETRY_BUTTON_LT_Y*8-4,
RETRY_BUTTON_RB_X*8, RETRY_BUTTON_RB_Y*8-4, &tpd.disp);
if(tpd.raw.validity==TP_VALIDITY_VALID) {
OS_Printf("( %3d, %3d ) -> ( %4d, %4d )\n", tpd.disp.x, tpd.disp.y, tpd.raw.x, tpd.raw.y);
}
}
if((pad.trg & PAD_BUTTON_A) || (tp_ok)) {
GetSYSMWork()->ncd_invalid = 0;
GetNCDWork()->option.input_tp = 1; // タッチパネル入力フラグを立てる。
GetNCDWork()->tp.raw_x1 = cw->sample[0].x;
GetNCDWork()->tp.raw_y1 = cw->sample[0].y;
GetNCDWork()->tp.dx1 = 32;
GetNCDWork()->tp.dy1 = 32;
GetNCDWork()->tp.raw_x2 = cw->sample[1].x;
GetNCDWork()->tp.raw_y2 = cw->sample[1].y;
GetNCDWork()->tp.dx2 = DISP_X_SIZE - 32;
GetNCDWork()->tp.dy2 = DISP_Y_SIZE - 32;
// ::::::::::::::::::::::::::::::::::::::::::::::
// NVRAMへの書き込み
// ::::::::::::::::::::::::::::::::::::::::::::::
(void)NVRAMm_WriteNitroConfigData (GetNCDWork());
ReturnMenu();
return 0;
}else if((pad.trg & PAD_BUTTON_START) || (tp_retry)) {
cw->seq = SEQ_INIT;
}
break;
}
/* flush cache of OAM buffers to main memory */
DC_FlushRange( oamBakS, sizeof(oamBakS) );
GXS_LoadOAM( oamBakS, 0, sizeof(oamBakS) );
MI_DmaFill32( 3, oamBakS, 192, sizeof(oamBakS) ); // Clear OAM buffer
// Bボタンキャンセル
if((pad.trg & PAD_BUTTON_B) || (tp_cancel)){
(void)TP_CalcCalibrateParam(&cw->calibrate,
GetNCDWork()->tp.raw_x1, GetNCDWork()->tp.raw_y1, (u16)GetNCDWork()->tp.dx1, (u16)GetNCDWork()->tp.dy1,
GetNCDWork()->tp.raw_x2, GetNCDWork()->tp.raw_y2, (u16)GetNCDWork()->tp.dx2, (u16)GetNCDWork()->tp.dy2);
TP_SetCalibrateParam(&cw->calibrate);
ReturnMenu();
return 0;
}
return 0;
}
// メニューに戻る
static void ReturnMenu(void)
{
OS_Free(cw); // キャリブレーション用変数の開放
cw = NULL;
OS_Printf("Free :CalibWork\n");
SEQ_MainMenu_init();
}
// キャリブレーション設定の初期化
void SEQ_TP_Calibration_init(void)
{
GXS_SetVisiblePlane(GX_PLANEMASK_NONE);
MI_CpuClearFast(bgBakS, sizeof(bgBakS));
ClearAllStringSJIS();
(void)DrawStringSJIS( 1, 0, YELLOW, (const u8 *)"TOUCH PANEL CALIBRATION");
if( initialSet ) {
(void)DrawStringSJIS( 8, 18, RED, (const u8 *)"Calibrate touch panel.");
}
DisplayInit();
GXS_SetVisiblePlane(GX_PLANEMASK_OBJ | GX_PLANEMASK_BG1);
cw=OS_Alloc(sizeof(CalibWork)); // キャリブレーション用変数の確保
#ifdef __IPL2_DEBUG
if(cw==NULL) OS_Panic("ARM9- Fail to allocate memory...\n");
#endif /* __IPL2_DEBUG */
OS_Printf("Alloc :CalibWork\n");
SVC_CpuClear(0x0000, cw, sizeof(CalibWork), 16);
SVC_CpuClear(0x0000, &tpd, sizeof(TpWork), 16);
cw->seq = SEQ_INIT;
}
// タッチパネル設定ポイント キャラデータ
const u16 bitmapOBJPoint[8 * 8 * 5] = {
0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, // 0 char
0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, // 0 char
0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, // 0 char
0xFFFF, 0xFFFF, 0xFFFF, 0x801F, 0x801F, 0xFFFF, 0xFFFF, 0xFFFF, // 0 char
0xFFFF, 0xFFFF, 0xFFFF, 0x801F, 0x801F, 0xFFFF, 0xFFFF, 0xFFFF, // 0 char
0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, // 0 char
0xFFFF, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0xFFFF, // 0 char
0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, // 0 char
0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, // 1 char
0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, // 1 char
0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, // 1 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 1 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 2 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 2 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 2 char
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x801F, 0x801F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 2 char
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x801F, 0x801F, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, // 3 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 3 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 3 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 3 char
0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, // 4 char
0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, // 4 char
0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, // 4 char
0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, // 4 char
};

View File

@ -0,0 +1,567 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: unicode.c
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.h>
#include <sysmenu.h>
#include "unicode.h"
#include "font.h"
// define data------------------------------------------
#define TBL8140_ELEM_NUM 0xbd // 8140tblの要素数
#define TBL849f_ELEM_NUM 0x20 // 849ftblの要素数
typedef struct SjisUtf16Pare {
u16 sjis;
u16 unicode;
}SjisUtf16Pare;
// extern data------------------------------------------
// function's prototype declaration---------------------
static u16 SearchUnicodeTable(u16 unicode, SjisUtf16Pare *tblp, int elem_num);
// global variable -------------------------------------
// static variable -------------------------------------
// const data -----------------------------------------
static const SjisUtf16Pare tblSJIS_UTF16_8140[ TBL8140_ELEM_NUM ];
static const SjisUtf16Pare tblSJIS_UTF16_849f[ TBL849f_ELEM_NUM ];
//======================================================
// SJIS-BEからUTF16-LEへの変換
//======================================================
void ExSJIS_BEtoUTF16_LE(u8 *sjisp, u16 *unip, u16 length)
{
u16 code;
while( (*sjisp) && (length-- > 0) ) {
if( ((*sjisp >= SJIS_HIGHER_CODE1_MIN) && (*sjisp <= SJIS_HIGHER_CODE1_MAX))
||((*sjisp >= SJIS_HIGHER_CODE2_MIN) && (*sjisp <= SJIS_HIGHER_CODE2_MAX)) ) { // SJISか
code = (u16)( (u16)*sjisp++ << 8 );
code |= (u16)*sjisp++;
}else { // ASCII
code = (u16)*sjisp++;
}
if(code == 0x005c)
{
*unip = 0x00a5; // \
}else if(code == 0x007e)
{
*unip = 0x203e; // ~
}else if( (code == 0x000d) || (code == 0x000a) ) {
*unip = code; // 改行コード
}else if( (code >= 0x0020) && (code < 0x007e) ) // ' ' }
{
*unip = code;
}else if( (code >= 0x00a1) && (code <= 0x00df) ) // 。
{
*unip = (u16)( (code - 0x00a1) + 0xff61 );
}else if( (code >= 0x8140) && (code <= 0x81fc) ) // ' '
{
// バラバラなので、テーブル引き
*unip = tblSJIS_UTF16_8140[ code - 0x8140 ].unicode;
}else if( (code >= 0x824f) && (code <= 0x8258) ) //
{
*unip = (u16)( (code - 0x824f) + 0xff10 );
}else if( (code >= 0x8260) && (code <= 0x8279) ) //
{
*unip = (u16)( (code - 0x8260) + 0xff21 );
}else if( (code >= 0x8281) && (code <= 0x829a) ) //
{
*unip = (u16)( (code - 0x8281) + 0xff41 );
}else if( (code >= 0x829f) && (code <= 0x82f1) ) // ぁ
{
*unip = (u16)( (code - 0x829f) + 0x3041 );
}else if( (code >= 0x8340) && (code <= 0x8396) ) // ァ ヶ ※0x837fは抜け
{
*unip = (u16)( (code - 0x8340) + 0x30a1 );
if( code == 0x837f ) {
*unip = 0x3000;
}else if( code > 0x837f ) {
(*unip)--;
}
}else if( (code >= 0x839f) && (code <= 0x83b6) ) // Α Ω
{
*unip = (u16)( (code - 0x839f) + 0x0391 );
if(code >= 0x83b0) (*unip)++;
}else if( (code >= 0x83bf) && (code <= 0x83d6) ) // α ω
{
*unip = (u16)( (code - 0x83bf) + 0x03b1 );
if (code >= 0x83d0) (*unip)++;
}else if( (code >= 0x8440) && (code <= 0x8460) ) // А Я
{
*unip = (u16)( (code - 0x8440) + 0x0410 );
if( code == 0x8446 ) {
*unip = 0x0401;
}else if( code > 0x8446 ){
(*unip)--;
}
}else if( (code >= 0x8470) && (code <= 0x8491) ) // а я ※0x847fは抜け
{
*unip = (u16)( (code - 0x8470) + 0x0430 );
if( code == 0x8476 ) {
*unip = 0x0451;
}else if( code == 0x847f ) {
*unip = 0x3000;
}else if( code > 0x8476 ){
(*unip)--;
if( code > 0x847f ){
(*unip)--;
}
}
}else if( (code >= 0x849f) && (code <= 0x84be) ) // ─
{
// バラバラなので、テーブル引き
*unip = tblSJIS_UTF16_849f[ code - 0x849f ].unicode;
}else {
*unip = 0x3000;
}
unip++;
}
}
//======================================================
// UTF16-LEからSJIS-BEへの変換
//======================================================
void ExUTF16_LEtoSJIS_BE(u8 *sjisp, u16 *unip, u16 length)
{
u16 code, sjis_le;
while( (*unip) && (length-- > 0) ) {
code = *unip++;
sjis_le = 0;
if(code == 0x00a5)
{
sjis_le = 0x005c; // \
}else if(code == 0x005c)
{
sjis_le = 0x815f; //
}else if(code == 0x203e)
{
sjis_le = 0x007e; // ~
}else if( (code == 0x000d) || (code == 0x000a) ) {
sjis_le = code; // 改行コード
}else if( (code >= 0x0020) && (code < 0x007e) ) // ' ' }
{
sjis_le = code;
}else if( (code >= 0x00a2) && (code <= 0x00f7) )
{ // Unicode = 0x00a2 - 0x00f7 は、 SJIS = 0x814c - 0x81f7に配置
sjis_le = SearchUnicodeTable(code, (SjisUtf16Pare *)&tblSJIS_UTF16_8140[0xc], 0x81f7 - 0x814c);
}else if( (code >= 0xff61) && (code <= 0xff9f) ) // 。
{
sjis_le = (u16)( (code - 0xff61) + 0x00a1 );
}else if(code == 0x4edd) {
sjis_le = 0x8157;
}else if( (code >= 0xff01) && (code <= 0xffe5) )
{
if( (code >= 0xff10) && (code <= 0xff19) ) //
{
sjis_le = (u16)( (code - 0xff10) + 0x824f );
}else if( (code >= 0xff21) && (code <= 0xff3a) ) //
{
sjis_le = (u16)( (code - 0xff21) + 0x8260 );
}else if( (code >= 0xff41) && (code <= 0xff5a) ) //
{
sjis_le = (u16)( (code - 0xff41) + 0x8281 );
}else { // Unicode = 0xff01 - 0xffe5 は、 SJIS = 0x8143 - 0x8197に配置
sjis_le = SearchUnicodeTable(code, (SjisUtf16Pare *)&tblSJIS_UTF16_8140[3], 0x8197 - 0x8143);
}
}else if( (code >= 0x3000) && (code <= 0x30fe) )
{
if( (code >= 0x3041) && (code <= 0x3093) ) // ぁ
{
sjis_le = (u16)( (code - 0x3041) + 0x829f );
}else if( (code >= 0x30a1) && (code <= 0x30f6) ) // ァ ヶ ※0x837fは抜け
{
sjis_le = (u16)( (code - 0x30a1) + 0x8340 );
if( code >= 0x30e0 ) {
(sjis_le)++;
}
}else { // Unicode = 0x3000 - 0x30fe は、 SJIS = 0x8140 - 0x81acに配置
sjis_le = SearchUnicodeTable(code, (SjisUtf16Pare *)&tblSJIS_UTF16_8140[0], 0x81ac - 0x8140);
}
}else if( (code >= 0x0391) && (code <= 0x03a9) ) // Α Ω
{
sjis_le = (u16)( (code - 0x0391) + 0x839f );
if(code >= 0x03a3) (sjis_le)--;
}else if( (code >= 0x03b1) && (code <= 0x03c9) ) // α ω
{
sjis_le = (u16)( (code - 0x03b1) + 0x83bf );
if (code >= 0x03c3) (sjis_le)--;
}else if( code == 0x0401 )
{
sjis_le = 0x8446;
}else if( (code >= 0x0410) && (code <= 0x042f) ) // А Я
{
sjis_le = (u16)( (code - 0x0410) + 0x8440 );
if( code >= 0x0416 ){
(sjis_le)++;
}
}else if( (code >= 0x0430) && (code <= 0x044f) ) // а я ※0x847fは抜け
{
sjis_le = (u16)( (code - 0x0430) + 0x8470 );
if( code >= 0x0436 ){
(sjis_le)++;
if( code >= 0x043e ){
(sjis_le)++;
}
}
}else if( code == 0x0451 )
{
sjis_le = 0x8476;
}else if( (code >= 0x2500) && (code <= 0x254b) ) // ─
{
sjis_le = SearchUnicodeTable(code, (SjisUtf16Pare *)&tblSJIS_UTF16_849f, TBL849f_ELEM_NUM);
}else if( ( (code >= 0x2010) && (code <= 0x2312) ) || ( (code >= 0x25a0) && (code <= 0x266f) ) )
{ // 上記コードは、 SJIS = 0x815c - 0x81fcに配置
sjis_le = SearchUnicodeTable(code, (SjisUtf16Pare *)&tblSJIS_UTF16_8140[0x815c - 0x8140], 0x81fc - 0x815c);
}else
{
sjis_le = 0x8140;
}
// 変換したSJISコードをバッファに格納
if( sjis_le & 0xff00) { // ASCIIコードでなければ、ビッグエンディアン形式で格納。
*sjisp++ = (u8)(sjis_le >> 8);
}
*sjisp++ = (u8)(sjis_le);
}
}
// Unicode -> SJISへのテーブル引き
static u16 SearchUnicodeTable(u16 unicode, SjisUtf16Pare *tblp, int elem_num)
{
elem_num++;
while(elem_num--) {
if(tblp->unicode == unicode) {
return tblp->sjis;
}
tblp++;
}
return 0x8140;
}
//======================================================
// SJIS-BE <-> UTF16-LE変換のチェック
//======================================================
void CheckSJIS_BEtoUTF16_LE(void)
{
u16 sjis, sjis_be, rev_sjis, sjis_le;
u16 unicode;
// ASCIIコードのチェック
for ( sjis = 0; sjis < 0x00ff; sjis++ ) {
unicode = 0;
rev_sjis = 0;
ExSJIS_BEtoUTF16_LE( (u8 *)&sjis, &unicode, 1);
ExUTF16_LEtoSJIS_BE( (u8 *)&rev_sjis, &unicode, 1);
sjis_le = (u16)( (rev_sjis >> 8) | (rev_sjis << 8) );
OS_Printf("0x%x\t-> 0x%x\t-> 0x%x\n", sjis, unicode, sjis_le);
}
// SJISコードのチェック
for ( sjis = 0x8140; sjis < 0x84ff; sjis++ ) {
unicode = 0;
rev_sjis = 0;
sjis_be = (u16)( (sjis >> 8) | (sjis << 8) );
ExSJIS_BEtoUTF16_LE( (u8 *)&sjis_be, &unicode, 1);
ExUTF16_LEtoSJIS_BE( (u8 *)&rev_sjis, &unicode, 1);
sjis_le = (u16)( (rev_sjis >> 8) | (rev_sjis << 8) );
OS_Printf("0x%x\t-> 0x%x\t-> 0x%x\n", sjis, unicode, sjis_le);
}
}
//======================================================
// SJISコード->Unicodeテーブル
//======================================================
// 0x8140
static const SjisUtf16Pare tblSJIS_UTF16_8140[ TBL8140_ELEM_NUM ] = {
{ 0x8140, 0x3000 }, //  
{ 0x8141, 0x3001 }, // 、
{ 0x8142, 0x3002 }, // 。
{ 0x8143, 0xFF0C }, //
{ 0x8144, 0xFF0E }, //
{ 0x8145, 0x30FB }, // ・
{ 0x8146, 0xFF1A }, //
{ 0x8147, 0xFF1B }, //
{ 0x8148, 0xFF1F }, //
{ 0x8149, 0xFF01 }, //
{ 0x814A, 0x309B }, // ゛
{ 0x814B, 0x309C }, // ゜
{ 0x814C, 0x00B4 }, // ´
{ 0x814D, 0xFF40 }, //
{ 0x814E, 0x00A8 }, // ¨
{ 0x814F, 0xFF3E }, //
{ 0x8150, 0xFFE3 }, //  ̄
{ 0x8151, 0xFF3F }, // _
{ 0x8152, 0x30FD }, // ヽ
{ 0x8153, 0x30FE }, // ヾ
{ 0x8154, 0x309D }, // ゝ
{ 0x8155, 0x309E }, // ゞ
{ 0x8156, 0x3003 }, // 〃
{ 0x8157, 0x4EDD }, // 仝
{ 0x8158, 0x3005 }, // 々
{ 0x8159, 0x3006 }, // 〆
{ 0x815A, 0x3007 }, //
{ 0x815B, 0x30FC }, // ー
{ 0x815C, 0x2015 }, // ―
{ 0x815D, 0x2010 }, //
{ 0x815E, 0xFF0F }, //
{ 0x815F, 0x005C }, //
{ 0x8160, 0x301C }, //
{ 0x8161, 0x2016 }, // ∥
{ 0x8162, 0xFF5C }, //
{ 0x8163, 0x2026 }, // …
{ 0x8164, 0x2025 }, // ‥
{ 0x8165, 0x2018 }, //
{ 0x8166, 0x2019 }, //
{ 0x8167, 0x201C }, // “
{ 0x8168, 0x201D }, // ”
{ 0x8169, 0xFF08 }, //
{ 0x816A, 0xFF09 }, //
{ 0x816B, 0x3014 }, //
{ 0x816C, 0x3015 }, //
{ 0x816D, 0xFF3B }, //
{ 0x816E, 0xFF3D }, //
{ 0x816F, 0xFF5B }, //
{ 0x8170, 0xFF5D }, //
{ 0x8171, 0x3008 }, // 〈
{ 0x8172, 0x3009 }, // 〉
{ 0x8173, 0x300A }, // 《
{ 0x8174, 0x300B }, // 》
{ 0x8175, 0x300C }, // 「
{ 0x8176, 0x300D }, // 」
{ 0x8177, 0x300E }, // 『
{ 0x8178, 0x300F }, // 』
{ 0x8179, 0x3010 }, // 【
{ 0x817A, 0x3011 }, // 】
{ 0x817B, 0xFF0B }, //
{ 0x817C, 0x2212 }, //
{ 0x817D, 0x00B1 }, // ±
{ 0x817E, 0x00D7 }, // ×
{ 0x817F, 0x3000 }, //
{ 0x8180, 0x00F7 }, // ÷
{ 0x8181, 0xFF1D }, //
{ 0x8182, 0x2260 }, // ≠
{ 0x8183, 0xFF1C }, //
{ 0x8184, 0xFF1E }, //
{ 0x8185, 0x2266 }, // ≦
{ 0x8186, 0x2267 }, // ≧
{ 0x8187, 0x221E }, // ∞
{ 0x8188, 0x2234 }, // ∴
{ 0x8189, 0x2642 }, // ♂
{ 0x818A, 0x2640 }, // ♀
{ 0x818B, 0x00B0 }, // °
{ 0x818C, 0x2032 }, //
{ 0x818D, 0x2033 }, // ″
{ 0x818E, 0x2103 }, // ℃
{ 0x818F, 0xFFE5 }, // ¥
{ 0x8190, 0xFF04 }, //
{ 0x8191, 0x00A2 }, // ¢
{ 0x8192, 0x00A3 }, // £
{ 0x8193, 0xFF05 }, //
{ 0x8194, 0xFF03 }, //
{ 0x8195, 0xFF06 }, //
{ 0x8196, 0xFF0A }, //
{ 0x8197, 0xFF20 }, //
{ 0x8198, 0x00A7 }, // §
{ 0x8199, 0x2606 }, // ☆
{ 0x819A, 0x2605 }, // ★
{ 0x819B, 0x25CB }, // ○
{ 0x819C, 0x25CF }, // ●
{ 0x819D, 0x25CE }, // ◎
{ 0x819E, 0x25C7 }, // ◇
{ 0x819F, 0x25C6 }, // ◆
{ 0x81A0, 0x25A1 }, // □
{ 0x81A1, 0x25A0 }, // ■
{ 0x81A2, 0x25B3 }, // △
{ 0x81A3, 0x25B2 }, // ▲
{ 0x81A4, 0x25BD }, // ▽
{ 0x81A5, 0x25BC }, // ▼
{ 0x81A6, 0x203B }, // ※
{ 0x81A7, 0x3012 }, // 〒
{ 0x81A8, 0x2192 }, // →
{ 0x81A9, 0x2190 }, // ←
{ 0x81AA, 0x2191 }, // ↑
{ 0x81AB, 0x2193 }, // ↓
{ 0x81AC, 0x3013 }, // 〓
{ 0x81AD, 0x3000 }, //
{ 0x81AE, 0x3000 }, //
{ 0x81AF, 0x3000 }, //
{ 0x81B0, 0x3000 }, //
{ 0x81B1, 0x3000 }, //
{ 0x81B2, 0x3000 }, //
{ 0x81B3, 0x3000 }, //
{ 0x81B4, 0x3000 }, //
{ 0x81B5, 0x3000 }, //
{ 0x81B6, 0x3000 }, //
{ 0x81B7, 0x3000 }, //
{ 0x81B8, 0x2208 }, // ∈
{ 0x81B9, 0x220B }, // ∋
{ 0x81BA, 0x2286 }, // ⊆
{ 0x81BB, 0x2287 }, // ⊇
{ 0x81BC, 0x2282 }, // ⊂
{ 0x81BD, 0x2283 }, // ⊃
{ 0x81BE, 0x222A }, //
{ 0x81BF, 0x2229 }, // ∩
{ 0x81C0, 0x3000 }, //
{ 0x81C1, 0x3000 }, //
{ 0x81C2, 0x3000 }, //
{ 0x81C3, 0x3000 }, //
{ 0x81C4, 0x3000 }, //
{ 0x81C5, 0x3000 }, //
{ 0x81C6, 0x3000 }, //
{ 0x81C7, 0x3000 }, //
{ 0x81C8, 0x2227 }, // ∧
{ 0x81C9, 0x2228 }, //
{ 0x81CA, 0x00AC }, // ¬
{ 0x81CB, 0x21D2 }, // ⇒
{ 0x81CC, 0x21D4 }, // ⇔
{ 0x81CD, 0x2200 }, // ∀
{ 0x81CE, 0x2203 }, // ∃
{ 0x81CF, 0x3000 }, //
{ 0x81D0, 0x3000 }, //
{ 0x81D1, 0x3000 }, //
{ 0x81D2, 0x3000 }, //
{ 0x81D3, 0x3000 }, //
{ 0x81D4, 0x3000 }, //
{ 0x81D5, 0x3000 }, //
{ 0x81D6, 0x3000 }, //
{ 0x81D7, 0x3000 }, //
{ 0x81D8, 0x3000 }, //
{ 0x81D9, 0x3000 }, //
{ 0x81DA, 0x2220 }, // ∠
{ 0x81DB, 0x22A5 }, // ⊥
{ 0x81DC, 0x2312 }, // ⌒
{ 0x81DD, 0x2202 }, // ∂
{ 0x81DE, 0x2207 }, // ∇
{ 0x81DF, 0x2261 }, // ≡
{ 0x81E0, 0x2252 }, // ≒
{ 0x81E1, 0x226A }, // ≪
{ 0x81E2, 0x226B }, // ≫
{ 0x81E3, 0x221A }, // √
{ 0x81E4, 0x223D }, // ∽
{ 0x81E5, 0x221D }, // ∝
{ 0x81E6, 0x2235 }, // ∵
{ 0x81E7, 0x222B }, // ∫
{ 0x81E8, 0x222C }, // ∬
{ 0x81E9, 0x3000 }, //
{ 0x81EA, 0x3000 }, //
{ 0x81EB, 0x3000 }, //
{ 0x81EC, 0x3000 }, //
{ 0x81EE, 0x3000 }, //
{ 0x81EE, 0x3000 }, //
{ 0x81EF, 0x3000 }, //
{ 0x81F0, 0x212B }, // Å
{ 0x81F1, 0x2030 }, // ‰
{ 0x81F2, 0x266F }, // ♯
{ 0x81F3, 0x266D }, // ♭
{ 0x81F4, 0x266A }, // ♪
{ 0x81F5, 0x2020 }, // †
{ 0x81F6, 0x2021 }, // ‡
{ 0x81F7, 0x00B6 }, // ¶
{ 0x81F8, 0x3000 }, //
{ 0x81F9, 0x3000 }, //
{ 0x81FA, 0x3000 }, //
{ 0x81FB, 0x3000 }, //
{ 0x81FC, 0x25EF }, // ◯
};
// 0x849f
// Unicodeでは、0x2500-0x254bの間
static const SjisUtf16Pare tblSJIS_UTF16_849f[ TBL849f_ELEM_NUM ] = {
{ 0x849F, 0x2500 }, // ─
{ 0x84A0, 0x2502 }, // │
{ 0x84A1, 0x250C }, // ┌
{ 0x84A2, 0x2510 }, // ┐
{ 0x84A3, 0x2518 }, // ┘
{ 0x84A4, 0x2514 }, // └
{ 0x84A5, 0x251C }, // ├
{ 0x84A6, 0x252C }, // ┬
{ 0x84A7, 0x2524 }, // ┤
{ 0x84A8, 0x2534 }, // ┴
{ 0x84A9, 0x253C }, // ┼
{ 0x84AA, 0x2501 }, // ━
{ 0x84AB, 0x2503 }, // ┃
{ 0x84AC, 0x250F }, // ┏
{ 0x84AD, 0x2513 }, // ┓
{ 0x84AE, 0x251B }, // ┛
{ 0x84AF, 0x2517 }, // ┗
{ 0x84B0, 0x2523 }, // ┣
{ 0x84B1, 0x2533 }, // ┳
{ 0x84B2, 0x252B }, // ┫
{ 0x84B3, 0x253B }, // ┻
{ 0x84B4, 0x254B }, // ╋
{ 0x84B5, 0x2520 }, // ┠
{ 0x84B6, 0x252F }, // ┯
{ 0x84B7, 0x2528 }, // ┨
{ 0x84B8, 0x2537 }, // ┷
{ 0x84B9, 0x253F }, // ┿
{ 0x84BA, 0x251D }, // ┝
{ 0x84BB, 0x2530 }, // ┰
{ 0x84BC, 0x2525 }, // ┥
{ 0x84BD, 0x2538 }, // ┸
{ 0x84BE, 0x2542 }, // ╂
};

View File

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: unicode.h
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$
*---------------------------------------------------------------------------*/
#ifndef __UNICODE_H_
#define __UNICODE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
// define data----------------------------------
// function's prototype declaration-------------
void ExSJIS_BEtoUTF16_LE(u8 *sjisp, u16 *unip, u16 length);
void ExUTF16_LEtoSJIS_BE(u8 *sjisp, u16 *unip, u16 length);
void CheckSJIS_BEtoUTF16_LE(void);
#ifdef __cplusplus
}
#endif
#endif // __UNICODE_H_

View File

@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: logoData.c
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.h>
#include "main.h"
// define data-----------------------------------------------------------
#define NIN_LOGO_LENGTH 0x9c // Nintendoロゴデータサイズ
#define OAM_OBJ_BLEND 0x00000400 // OBJ半透明モード
#define OAM_SIZE_64x32 0xc0004000 // 64x32ドット
#define OAM_COLOR_256 0x00002000 // 256色 選択
#define OAM_AFFINE_NONE 0x00000000 // アフィン無効モード
#define OAM_V_POS_SHIFT 0
#define OAM_H_POS_SHIFT 16
#define OAM_AFFINE_NO_SHIFT 25
#define OAM_PRIORITY_SHIFT 10
#define OAM_PLTT_SHIFT 12
// extern data-----------------------------------------------------------
// function's prototype--------------------------------------------------
void LoadLogoData( void );
static void UnCompNintendoLogo( u16 *NintendoLogoDatap, u16 *dstp, u32 *temp );
static void SVC_DiffUnFilter16_16( u16 *srcp,u16 *dstp );
static s32 MEMB_InitFunc( const u8 *devicep, void *ramp, const void *paramp );
static s32 MEMB_TerminateFunc( const u8 *devicep );
static u8 MEMB_ByteStreamFunc( const u8 *devicep );
static u32 MEMB_WordStreamFunc( const u8 *devicep );
// global variable-------------------------------------------------------
// static variable-------------------------------------------------------
// const data------------------------------------------------------------
const u32 OamLogoData[ 2 ][ 2 ] = {
{
OAM_OBJ_BLEND | OAM_SIZE_64x32 | OAM_AFFINE_NONE | OAM_COLOR_256 |
71 << OAM_H_POS_SHIFT |
88 << OAM_V_POS_SHIFT |
0 << OAM_AFFINE_NO_SHIFT,
0 << 1 | 5 << OAM_PLTT_SHIFT | 2 << OAM_PRIORITY_SHIFT
},
{
OAM_OBJ_BLEND | OAM_SIZE_64x32 | OAM_AFFINE_NONE | OAM_COLOR_256 |
71 + 64 << OAM_H_POS_SHIFT |
88 << OAM_V_POS_SHIFT |
0 << OAM_AFFINE_NO_SHIFT,
8 << 1 | 5 << OAM_PLTT_SHIFT | 2 << OAM_PRIORITY_SHIFT
},
};
static const MIReadStreamCallbacks memb_ifp={
MEMB_InitFunc,
MEMB_TerminateFunc,
MEMB_ByteStreamFunc,
NULL,
MEMB_WordStreamFunc,
};
static const MIUnpackBitsParam Nin_UnPackBitsParam={
(8*8/2)*( 7*2), 1, 8, 0x1e, 0
};
static const u8 Nin_Char_Diff_Huff_Table[] = {
0x24,0xd4,0x00,0x00,
0x0f,0x40,0x00,0x00,0x00,0x01,0x81,0x82,0x82,0x83,0x0f,0x83,0x0c,0xc3,0x03,0x83,
0x01,0x83,0x04,0xc3,0x08,0x0e,0x02,0xc2,0x0d,0xc2,0x07,0x0b,0x06,0x0a,0x05,0x09,
};
static const u8 Nin_Char_Diff_Huff[] ATTRIBUTE_ALIGN( 2 ) = {
0x24, 0xff, 0xae, 0x51, 0x69, 0x9a, 0xa2, 0x21, 0x3d, 0x84, 0x82, 0x0a, 0x84, 0xe4, 0x09, 0xad,
0x11, 0x24, 0x8b, 0x98, 0xc0, 0x81, 0x7f, 0x21, 0xa3, 0x52, 0xbe, 0x19, 0x93, 0x09, 0xce, 0x20,
0x10, 0x46, 0x4a, 0x4a, 0xf8, 0x27, 0x31, 0xec, 0x58, 0xc7, 0xe8, 0x33, 0x82, 0xe3, 0xce, 0xbf,
0x85, 0xf4, 0xdf, 0x94, 0xce, 0x4b, 0x09, 0xc1, 0x94, 0x56, 0x8a, 0xc0, 0x13, 0x72, 0xa7, 0xfc,
0x9f, 0x84, 0x4d, 0x73, 0xa3, 0xca, 0x9a, 0x61, 0x58, 0x97, 0xa3, 0x27, 0xfc, 0x03, 0x98, 0x76,
0x23, 0x1d, 0xc7, 0x61, 0x03, 0x04, 0xae, 0x56, 0xbf, 0x38, 0x84, 0x00, 0x40, 0xa7, 0x0e, 0xfd,
0xff, 0x52, 0xfe, 0x03, 0x6f, 0x95, 0x30, 0xf1, 0x97, 0xfb, 0xc0, 0x85, 0x60, 0xd6, 0x80, 0x25,
0xa9, 0x63, 0xbe, 0x03, 0x01, 0x4e, 0x38, 0xe2, 0xf9, 0xa2, 0x34, 0xff, 0xbb, 0x3e, 0x03, 0x44,
0x78, 0x00, 0x90, 0xcb, 0x88, 0x11, 0x3a, 0x94, 0x65, 0xc0, 0x7c, 0x63, 0x87, 0xf0, 0x3c, 0xaf,
0xd6, 0x25, 0xe4, 0x8b, 0x38, 0x0a, 0xac, 0x72, 0x21, 0xd4, 0xf8, 0x07, 0x56, 0xcf, 0x00, 0x00,
};
// ============================================================================
// ロゴデータロード
// ============================================================================
void LoadLogoData(void)
{
u32 temp[ 0x500 / sizeof(u32) ];
u16 *pBuff = NNS_FndAllocFromAllocator( &g_allocator, 0x1000 );
MI_CpuClear32( pBuff, 0x1000 );
if( pBuff == NULL ) {
OS_TPrintf( " %s : memory allocate error.\n", __FUNCTION__ );
return;
}
UnCompNintendoLogo( (u16 *)Nin_Char_Diff_Huff, pBuff, temp ); // NintendoロゴをpBuffに展開
MI_CpuCopy32( pBuff, (u32 *)HW_OBJ_VRAM, 0x340 ); // OBJ-VRAMにロード
MI_CpuCopy32( (void *)( (u32)pBuff + 0x340 ), (u32 *)( HW_OBJ_VRAM + 0x400 ), 8*8*13 );
*(vu16 *)( HW_OBJ_PLTT + 0x3e ) = 0x0000; // OBJパレットセット
*(vu16 *)HW_BG_PLTT = 0xffff; // バックドロップを「白」にする。
MI_CpuCopy32( OamLogoData, (u32 *)HW_OAM, sizeof(OamLogoData) ); // Nintendoロゴ用OAMデータセット
NNS_FndFreeToAllocator( &g_allocator, pBuff );
}
// Nintendoロゴ展開ルーチン (r0=ロゴ圧縮データ r1=展開先アドレス)
#include <nitro/code16.h>
asm void UnCompNintendoLogo(u16 *NintendoLogoDatap, u16 *dstp, u32 *temp)
{
push {r0-r2,r4, lr}
ldr r0, =Nin_Char_Diff_Huff_Table
mov r2, #0x0e
lsl r2, r2, #8
add r1, r1, r2 // 引数1+0xe00
mov r4, r1
mov r2, #36
bl MIi_CpuCopy16 // Nintendoロゴの圧縮テーブル部分のみをコピーしてくる
ldr r0, [sp, #0] // 引数NinLogoBak[36])
mov r2, #36
add r1, r4, r2 // 引数1+0xe00+36
mov r2, #NIN_LOGO_LENGTH
bl MIi_CpuCopy16 // 引数からNintendoロゴデータ本体をコピーしてくる
mov r0, r4 // 引数1+0xe00
ldr r1, [sp, #4] // 引数1
ldr r2, [sp, #8] // 引数2
ldr r3, =memb_ifp
bl SVC_UncompressHuffmanFromDevice // ハフマン展開
ldr r0, [sp, #4]
ldr r2, =0x0000d082
str r2, [r0,#0]
mov r1, r4 // 引数1+0xe00
bl SVC_DiffUnFilter16_16 // Diff展開
mov r0, r4 // 引数1+0xe00
ldr r1, [sp, #4] // 引数1
ldr r2, =Nin_UnPackBitsParam
bl SVC_UnpackBits // ビット展開
pop {r0-r2,r4, pc}
}
// 差分フィルタ展開システムコール16Bit→16Bit (r0=Srcp, r1=Destp)
static asm void SVC_DiffUnFilter16_16(u16 *srcp,u16 *dstp)
{
swi 24
bx lr
}
#include <nitro/codereset.h>
// ============================================================================
// バイトアクセス可能メモリ用アクセスルーチン群
// ============================================================================
static s32 MEMB_InitFunc(const u8 *devicep, void *ramp, const void *paramp)
{
#pragma unused(ramp)
if(paramp) return (s32)MEMB_WordStreamFunc(devicep);
else return 0;
}
static s32 MEMB_TerminateFunc(const u8 *devicep)
{
#pragma unused(devicep)
return 0;
}
static u8 MEMB_ByteStreamFunc(const u8 *devicep)
{
return *devicep;
}
static u32 MEMB_WordStreamFunc(const u8 *devicep)
{
return *(u32 *)devicep;
}

View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: logoDemo.c
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 "logoDemo.h"
// define data--------------------------------------------------------
#define LOGO_DISP_FRAME 60 // ロゴ表示フレーム数
// ロゴ表示ステータス構造体
typedef struct LogoStatus {
s32 state;
BOOL enable;
s32 value_A;
s32 value_B;
s32 mainCounter;
}LogoStatus;
// extern data--------------------------------------------------------
extern void LoadLogoData( void );
// function's prototype-----------------------------------------------
// static variables---------------------------------------------------
static LogoStatus s_logo = { 0, TRUE, 0, 0, 0 };
// const data---------------------------------------------------------
static void LogoInit( void )
{
// 画面OFF
GX_DispOff();
GXS_DispOff();
// VRAM割り当てクリア
GX_SetBankForOBJ( GX_VRAM_OBJ_128_A ); //       OBJ用
GX_SetGraphicsMode( GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D );
MI_CpuClearFast( (void *)HW_OBJ_VRAM, 0x1000 ); // OBJ-VRAM クリア
MI_DmaFill32( 3, (void *)HW_OAM, 192, HW_OAM_SIZE ); // OAM クリア
// 画面設定
GX_SetGraphicsMode( GX_DISPMODE_GRAPHICS, GX_BGMODE_2, GX_BG0_AS_2D );
GX_SetOBJVRamModeChar( GX_OBJVRAMMODE_CHAR_2D );
G2_SetBlendAlpha( GX_BLEND_PLANEMASK_OBJ, GX_BLEND_PLANEMASK_BD, s_logo.value_A, s_logo.value_B );
GX_SetVisiblePlane( GX_PLANEMASK_OBJ );
// ロゴデータロード
LoadLogoData();
s_logo.value_A = 0;
s_logo.value_B = 16;
// メイン画面のみON
GX_DispOn();
}
// ロゴメイン
int LogoMain()
{
if( !IsLogoEnable() ) {
return 1;
}
switch( s_logo.state ) {
case 0: // 初期設定
LogoInit();
s_logo.mainCounter = 0;
s_logo.state++;
break;
case 1: // Nintendoロゴフェードイン
if( s_logo.mainCounter++ < 16 ){ // Nintendoロゴ 表示
G2_ChangeBlendAlpha( ++s_logo.value_A, --s_logo.value_B );
}else {
s_logo.mainCounter = 0;
s_logo.state++;
}
break;
case 2: // Nintendoロゴ表示
if( s_logo.mainCounter++ == LOGO_DISP_FRAME ) {
s_logo.mainCounter = 0;
s_logo.state++;
}
break;
case 3: // Nintendoロゴフェードアウト
if( s_logo.mainCounter++ < 16 ) {
G2_ChangeBlendAlpha( --s_logo.value_A, ++s_logo.value_B );
}else {
return 1;
}
break;
default:
break;
}
return 0;
}
// ロゴ表示をOFFにする。
void SetLogoEnable( BOOL enable )
{
s_logo.enable = enable;
}
// ロゴ表示状態取得
BOOL IsLogoEnable(void)
{
return s_logo.enable;
}

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: logoDemo.h
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$
*---------------------------------------------------------------------------*/
#ifndef _LOGO_DEMO_H
#define _LOGO_DEMO_H
#include <twl.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void LoadLogo( void );
extern int LogoMain( void );
extern void SetLogoEnable( BOOL enable );
extern BOOL IsLogoEnable( void );
#ifdef __cplusplus
}
#endif
#endif /* _LOGO_DEMO_H */

View File

@ -0,0 +1,244 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL
File: launcher.c
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.h>
#include "main.h"
#include "logoDemo.h"
#include "DS_Setting.h"
// define data------------------------------------------
#define LAUNCHER_ELEMENT_NUM 4 // ロゴメニューの項目数
#define B_LIGHT_BUTTON_TOP_X 24
#define B_LIGHT_BUTTON_TOP_Y 21
#define B_LIGHT_BUTTON_BOTTOM_X ( B_LIGHT_BUTTON_TOP_X + 7 )
#define B_LIGHT_BUTTON_BOTTOM_Y ( B_LIGHT_BUTTON_TOP_Y + 2 )
// extern data------------------------------------------
// function's prototype declaration---------------------
static void DrawBackLightSwitch(void);
static void DrawLauncher(u16 nowCsr, const MenuParam *pMenu);
// global variable -------------------------------------
// static variable -------------------------------------
static u16 s_csr = 0; // メニューのカーソル位置
static const u16 *s_pStrLauncher[ LAUNCHER_ELEMENT_NUM ]; // ロゴメニュー用文字テーブルへのポインタリスト
// const data -----------------------------------------
//===============================================
// Launcher.c
//===============================================
static const u16 *const s_pStrLauncherElemTbl[ LAUNCHER_ELEMENT_NUM ][ LANG_CODE_MAX ] = {
{
(const u16 *)L"DSカード",
(const u16 *)L"DS Card",
(const u16 *)L"DS Card(F)",
(const u16 *)L"DS Card(G)",
(const u16 *)L"DS Card(I)",
(const u16 *)L"DS Card(S)",
},
{
(const u16 *)L"ピクトチャット",
(const u16 *)L"PictoChat",
(const u16 *)L"PictoChat(F)",
(const u16 *)L"PictoChat(G)",
(const u16 *)L"PictoChat(I)",
(const u16 *)L"PictoChat(S)",
},
{
(const u16 *)L"DSダウンロードプレイ",
(const u16 *)L"DS Download Play",
(const u16 *)L"DS Download Play(F)",
(const u16 *)L"DS Download Play(G)",
(const u16 *)L"DS Download Play(I)",
(const u16 *)L"DS Download Play(S)",
},
{
(const u16 *)L"本体設定",
(const u16 *)L"Machine Settings",
(const u16 *)L"Machine Settings(F)",
(const u16 *)L"Machine Settings(G)",
(const u16 *)L"Machine Settings(I)",
(const u16 *)L"Machine Settings(S)",
},
};
static MenuPos s_launcherPos[] = {
{ TRUE, 4 * 8, 8 * 8 },
{ TRUE, 4 * 8, 10 * 8 },
{ TRUE, 4 * 8, 12 * 8 },
{ TRUE, 4 * 8, 14 * 8 },
{ TRUE, 4 * 8, 16 * 8 },
};
static const MenuParam s_launcherParam = {
LAUNCHER_ELEMENT_NUM,
TXT_COLOR_BLACK,
TXT_COLOR_GREEN,
TXT_COLOR_RED,
&s_launcherPos[0],
(const u16 **)&s_pStrLauncher,
};
static const u16 *const str_backlight[] = {
(const u16 *)L"BLT:ON ",
(const u16 *)L"BLT:OFF",
};
//======================================================
// ランチャー
//======================================================
// ランチャーの初期化
void LauncherInit(void)
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_WHITE );
GX_DispOn();
DrawBackLightSwitch();
PrintfSJIS( 0, 0, TXT_COLOR_BLUE, "TWL-SYSTEM MENU ver.%06x", SYSMENU_VER );
// NITRO設定データのlanguageに応じたメインメニュー構成言語の切り替え
{
int i;
NvLangCode langCode = LANG_ENGLISH;
if( GetSYSMWork()->ncd_invalid == 0 ) {
langCode = (NvLangCode)GetNCDWork()->option.language;
}
for( i = 0; i < LAUNCHER_ELEMENT_NUM; i++ ) {
s_pStrLauncher[ i ] = s_pStrLauncherElemTbl[ i ][ langCode ];
}
}
if( !SYSM_IsNITROCard() ) {
s_launcherPos[ 0 ].enable = FALSE; // DSカードが無い時は、先頭要素を無効にする。
}
InitGetAndDrawRtcData( RTC_DATE_TOP_X, RTC_DATE_TOP_Y, RTC_TIME_TOP_X, RTC_TIME_TOP_Y );
DrawLauncher( s_csr, &s_launcherParam );
SVC_CpuClear( 0x0000, &tpd, sizeof(TpWork), 16 );
GX_SetVisiblePlane( GX_PLANEMASK_BG0 );
}
// ランチャーメイン
IPL2BootType LauncherMain( BOOL boot_decision )
{
#pragma unused( boot_decision )
static BOOL touch_bl = FALSE;
BOOL tp_bl_on_off = FALSE;
BOOL tp_select = FALSE;
u16 csr_old;
// RTC情報の取得表示
GetAndDrawRtcData();
//--------------------------------------
// バックライトON,OFF制御
//--------------------------------------
if(tpd.disp.touch) {
BOOL range = InRangeTp( B_LIGHT_BUTTON_TOP_X*8, B_LIGHT_BUTTON_TOP_Y*8-4,
B_LIGHT_BUTTON_BOTTOM_X*8, B_LIGHT_BUTTON_BOTTOM_Y*8-4, &tpd.disp );
if( range && !touch_bl ) {
touch_bl = TRUE;
tp_bl_on_off = TRUE;
}
}else {
touch_bl = FALSE;
}
if( (pad.trg & PAD_BUTTON_R) || (tp_bl_on_off) ) {
GetNCDWork()->option.backLightOffFlag ^= 0x01;
DrawBackLightSwitch();
}
//--------------------------------------
// キー入力処理
//--------------------------------------
if(pad.trg & PAD_KEY_DOWN){ // カーソルの移動
if( ++s_csr == LAUNCHER_ELEMENT_NUM ) {
s_csr = 0;
}
}
if( pad.trg & PAD_KEY_UP ){
if( --s_csr & 0x80 ) {
s_csr = LAUNCHER_ELEMENT_NUM - 1;
}
}
csr_old = s_csr;
tp_select = SelectMenuByTP( &s_csr, &s_launcherParam );
DrawLauncher( s_csr, &s_launcherParam );
if( ( pad.trg & PAD_BUTTON_A ) || ( tp_select ) ) { // メニュー項目への分岐
if( s_launcherPos[ 0 ].enable ) {
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_WHITE );
return (IPL2BootType)( s_csr + 1 );
}
}
return (IPL2BootType)0;
}
// ランチャー描画
static void DrawLauncher(u16 nowCsr, const MenuParam *pMenu)
{
int i;
int color;
for( i = 0; i < pMenu->num; i++ ) {
if(i == nowCsr) {
if( !pMenu->pos[ i ].enable ) {
color = pMenu->disable_color;
}else {
color = pMenu->select_color;
}
}else {
color = pMenu->normal_color;
}
PutStringUTF16( pMenu->pos[ i ].x, pMenu->pos[ i ].y, color, (pMenu->str_elem)[ i ] );
}
}
// バックライトスイッチの表示
static void DrawBackLightSwitch(void)
{
u16 color;
if( GetNCDWork()->option.backLightOffFlag ) {
color = TXT_COLOR_BLACK;
}else {
color = TXT_COLOR_RED;
}
PutStringUTF16( B_LIGHT_BUTTON_TOP_X, B_LIGHT_BUTTON_TOP_Y, color,
str_backlight[ GetNCDWork()->option.backLightOffFlag ] );
}

Some files were not shown because too many files have changed in this diff Show More