3.4.4 release commit...

* More unused/unusable features removed.
*  Top screen logo updated to have more flashcart logos. Thanks to
SylverReZ for most of the added logos.
This commit is contained in:
ApacheThunder 2023-11-11 12:38:57 -06:00
parent 1882568781
commit a10debc12f
69 changed files with 120 additions and 20620 deletions

4
.gitignore vendored
View File

@ -6,6 +6,10 @@
*.cmd
data/*.bin
title/
gm9n_bootstrap/arm9/build
gm9n_bootstrap/arm7/build
gm9n_bootstrap/data
gm9n_bootstrap/bootloader/*.bin
.vscode
*.DS_Store

View File

@ -1,5 +1,5 @@
export ARM7_MAJOR := 0
export ARM7_MINOR := 6
export ARM7_MINOR := 7
export ARM7_PATCH := 0
VERSTRING := $(ARM7_MAJOR).$(ARM7_MINOR).$(ARM7_PATCH)

View File

@ -162,6 +162,7 @@ int main() {
REG_SCFG_CLK = 0x187;
REG_SCFG_EXT = 0x92A40000;
for (int i = 0; i < 10; i++) { while(REG_VCOUNT!=191); while(REG_VCOUNT==191); }
REG_SCFG_EXT &= ~(1UL << 31);
// scfgUnlocked = true;
}
@ -172,25 +173,11 @@ int main() {
// Keep the ARM7 mostly idle
while (!exitflag) {
if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R)))exitflag = true;
if (*(u32*)(0x2FFFD0C) == 0x454D4D43) {
my_sdmmc_get_cid(true, (u32*)0x2FFD7BC); // Get eMMC CID
*(u32*)(0x2FFFD0C) = 0;
}
resyncClock();
// Send SD status
if(isDSiMode() || *(u16*)(0x4004700) != 0)fifoSendValue32(FIFO_USER_04, SD_IRQ_STATUS);
// Dump EEPROM save
if(fifoCheckAddress(FIFO_USER_01)) {
switch(fifoGetValue32(FIFO_USER_01)) {
case 0x44414552: // 'READ'
readEeprom((u8 *)fifoGetAddress(FIFO_USER_01), fifoGetValue32(FIFO_USER_01), fifoGetValue32(FIFO_USER_01));
break;
case 0x54495257: // 'WRIT'
writeEeprom(fifoGetValue32(FIFO_USER_01), (u8 *)fifoGetAddress(FIFO_USER_01), fifoGetValue32(FIFO_USER_01));
break;
}
}
swiWaitForVBlank();
while(REG_VCOUNT!=191);
while(REG_VCOUNT==191);
}
return 0;
}

View File

@ -37,8 +37,8 @@ endif
#---------------------------------------------------------------------------------
TARGET := GodMode9Nrio
BUILD := build
SOURCES := source source/flashcard source/graphics dldi-include mbedtls
INCLUDES := include source source/flashcard source/graphics
SOURCES := source source/graphics
INCLUDES := include source source/graphics
DATA := ../data
GRAPHICS := ../gfx

View File

@ -4,3 +4,4 @@
bool screenshot(void);
#endif // SCREENSHOT_H

View File

@ -1,252 +0,0 @@
#include <nds.h>
#include <malloc.h>
#include "aes.h"
/* AES 128 ECB dug out from mbed TLS 2.5.1
* https://github.com/ARMmbed/mbedtls/blob/development/include/mbedtls/aes.h
* https://github.com/ARMmbed/mbedtls/blob/development/library/aes.c
*
* C style comments are mbed TLS comments
* C++ style comments are mine
*/
// make VC happy
#ifdef _MSC_VER
#define DTCM_BSS
#define ITCM_CODE
#endif
// it's interesting they mix unsigned char with uint32_t
DTCM_BSS static unsigned char FSb[256];
DTCM_BSS static uint32_t FT0[256];
DTCM_BSS static uint32_t FT1[256];
DTCM_BSS static uint32_t FT2[256];
DTCM_BSS static uint32_t FT3[256];
// AES-CTR/CCM only uses encrypt, so R tables are not used
#define NO_R_TABLES
#ifndef NO_R_TABLES
static unsigned char RSb[256];
static uint32_t RT0[256];
static uint32_t RT1[256];
static uint32_t RT2[256];
static uint32_t RT3[256];
#endif
static uint32_t RCON[256];
/*
* Tables generation code
*/
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
void aes_gen_tables(void)
{
#ifdef NO_R_TABLES
unsigned char *RSb = memalign(32, 256);
uint32_t *RT0 = memalign(32, 256 * sizeof(uint32_t));
uint32_t *RT1 = memalign(32, 256 * sizeof(uint32_t));
uint32_t *RT2 = memalign(32, 256 * sizeof(uint32_t));
uint32_t *RT3 = memalign(32, 256 * sizeof(uint32_t));
#endif
int i, x, y, z;
int pow[256];
int log[256];
/*
* compute pow and log tables over GF(2^8)
*/
for (i = 0, x = 1; i < 256; i++)
{
pow[i] = x;
log[x] = i;
x = (x ^ XTIME(x)) & 0xFF;
}
/*
* calculate the round constants
*/
for (i = 0, x = 1; i < 10; i++)
{
RCON[i] = (uint32_t)x;
x = XTIME(x) & 0xFF;
}
/*
* generate the forward and reverse S-boxes
*/
FSb[0x00] = 0x63;
RSb[0x63] = 0x00;
for (i = 1; i < 256; i++)
{
x = pow[255 - log[i]];
y = x; y = ((y << 1) | (y >> 7)) & 0xFF;
x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF;
x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF;
x ^= y; y = ((y << 1) | (y >> 7)) & 0xFF;
x ^= y ^ 0x63;
FSb[i] = (unsigned char)x;
RSb[x] = (unsigned char)i;
}
/*
* generate the forward and reverse tables
*/
for (i = 0; i < 256; i++)
{
x = FSb[i];
y = XTIME(x) & 0xFF;
z = (y ^ x) & 0xFF;
FT0[i] = ((uint32_t)y) ^
((uint32_t)x << 8) ^
((uint32_t)x << 16) ^
((uint32_t)z << 24);
FT1[i] = ROTL8(FT0[i]);
FT2[i] = ROTL8(FT1[i]);
FT3[i] = ROTL8(FT2[i]);
x = RSb[i];
RT0[i] = ((uint32_t)MUL(0x0E, x)) ^
((uint32_t)MUL(0x09, x) << 8) ^
((uint32_t)MUL(0x0D, x) << 16) ^
((uint32_t)MUL(0x0B, x) << 24);
RT1[i] = ROTL8(RT0[i]);
RT2[i] = ROTL8(RT1[i]);
RT3[i] = ROTL8(RT2[i]);
}
#ifdef NO_R_TABLES
free(RSb);
free(RT0);
free(RT1);
free(RT2);
free(RT3);
#endif
}
// did a little counting to understand why original mbedTLS buf is [68]
// in set key, they generated:
// 128 bits key: 10 rounds of += 4, plus 4 after, 44
// 192 bits key: 8 rounds of += 6, plus 6 after, 56
// 256 bits key: 7 rounds of += 8, plus 8 after, 64
// and in ecb encrypt, it used:
// 4 + 4 * 2 * 4 + 4 + 4 "++"s, 44
// 4 + 4 * 2 * 5 + 4 + 4 "++"s, 52
// 4 + 4 * 2 * 6 + 4 + 4 "++"s, 60
// so they generated several bytes more in 192 and 256 modes to simplify the loop
// "able to hold 32 extra bytes" in their comment makes senses now
void aes_set_key_enc_128_be(uint32_t rk[RK_LEN], const unsigned char *key) {
uint32_t *RK = rk;
GET_UINT32_BE(RK[0], key, 12);
GET_UINT32_BE(RK[1], key, 8);
GET_UINT32_BE(RK[2], key, 4);
GET_UINT32_BE(RK[3], key, 0);
for (unsigned i = 0; i < 10; ++i, RK += 4) {
RK[4] = RK[0] ^ RCON[i] ^
((uint32_t)FSb[(RK[3] >> 8) & 0xFF]) ^
((uint32_t)FSb[(RK[3] >> 16) & 0xFF] << 8) ^
((uint32_t)FSb[(RK[3] >> 24) & 0xFF] << 16) ^
((uint32_t)FSb[(RK[3]) & 0xFF] << 24);
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
RK[7] = RK[3] ^ RK[6];
}
}
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
{ \
X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y3 >> 24 ) & 0xFF ]; \
\
X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y0 >> 24 ) & 0xFF ]; \
\
X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y1 >> 24 ) & 0xFF ]; \
\
X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
FT3[ ( Y2 >> 24 ) & 0xFF ]; \
}
DTCM_BSS uint32_t X0, X1, X2, X3, Y0, Y1, Y2, Y3;
DTCM_BSS const uint32_t *RK;
ITCM_CODE void aes_encrypt_128_be(const uint32_t rk[RK_LEN],
const unsigned char input[16], unsigned char output[16])
{
RK = rk;
GET_UINT32_BE(X0, input, 12);
GET_UINT32_BE(X1, input, 8);
GET_UINT32_BE(X2, input, 4);
GET_UINT32_BE(X3, input, 0);
X0 ^= *RK++;
X1 ^= *RK++;
X2 ^= *RK++;
X3 ^= *RK++;
// loop unrolled
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);
AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);
X0 = *RK++ ^ \
((uint32_t)FSb[(Y0) & 0xFF]) ^
((uint32_t)FSb[(Y1 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y2 >> 16) & 0xFF] << 16) ^
((uint32_t)FSb[(Y3 >> 24) & 0xFF] << 24);
X1 = *RK++ ^ \
((uint32_t)FSb[(Y1) & 0xFF]) ^
((uint32_t)FSb[(Y2 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y3 >> 16) & 0xFF] << 16) ^
((uint32_t)FSb[(Y0 >> 24) & 0xFF] << 24);
X2 = *RK++ ^ \
((uint32_t)FSb[(Y2) & 0xFF]) ^
((uint32_t)FSb[(Y3 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y0 >> 16) & 0xFF] << 16) ^
((uint32_t)FSb[(Y1 >> 24) & 0xFF] << 24);
// removed a ++ here
X3 = *RK ^ \
((uint32_t)FSb[(Y3) & 0xFF]) ^
((uint32_t)FSb[(Y0 >> 8) & 0xFF] << 8) ^
((uint32_t)FSb[(Y1 >> 16) & 0xFF] << 16) ^
((uint32_t)FSb[(Y2 >> 24) & 0xFF] << 24);
PUT_UINT32_BE(X0, output, 12);
PUT_UINT32_BE(X1, output, 8);
PUT_UINT32_BE(X2, output, 4);
PUT_UINT32_BE(X3, output, 0);
}

View File

@ -1,32 +0,0 @@
#pragma once
#include <stdint.h>
#define RK_LEN 44 //round key length
// modified to work on reversed byte order input/output
// it could work by wrapping it between byte reversed I/O, minmize modification to actual AES code
// this is just my OCD to eliminate some copy
// original mbedTLS AES GET/PUT_UINT32 macros on little endian I/O regardless of CPU endianness
// seems like Nintendo used big endian hardware AES with little endian CPU
// by byte reversing on I/O, this mimics Nintendo behavior on little endian CPU
// calling it BE is not very accurate, it becomes little endian on big endian CPU
#define GET_UINT32_BE(n, b, i) \
((uint8_t*)&(n))[0] = (b)[i + 3]; \
((uint8_t*)&(n))[1] = (b)[i + 2]; \
((uint8_t*)&(n))[2] = (b)[i + 1]; \
((uint8_t*)&(n))[3] = (b)[i + 0]
#define PUT_UINT32_BE(n, b, i) \
(b)[i + 0] = ((uint8_t*)&(n))[3]; \
(b)[i + 1] = ((uint8_t*)&(n))[2]; \
(b)[i + 2] = ((uint8_t*)&(n))[1]; \
(b)[i + 3] = ((uint8_t*)&(n))[0]
void aes_gen_tables(void);
void aes_set_key_enc_128_be(uint32_t rk[RK_LEN], const unsigned char *key);
void aes_encrypt_128_be(const uint32_t rk[RK_LEN], const unsigned char input[16], unsigned char output[16]);

File diff suppressed because it is too large Load Diff

View File

@ -1,761 +0,0 @@
/**
* \file bignum.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#include <stdint.h>
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */
#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 )
/*
* Maximum size MPIs are allowed to grow to in number of limbs.
*/
#define MBEDTLS_MPI_MAX_LIMBS 10000
#if !defined(MBEDTLS_MPI_WINDOW_SIZE)
/*
* Maximum window size used for modular exponentiation. Default: 6
* Minimum value: 1. Maximum value: 6.
*
* Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used
* for the sliding window calculation. (So 64 by default)
*
* Reduction in size, reduces speed.
*/
#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
#endif /* !MBEDTLS_MPI_WINDOW_SIZE */
#if !defined(MBEDTLS_MPI_MAX_SIZE)
/*
* Maximum size of MPIs allowed in bits and bytes for user-MPIs.
* ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits )
*
* Note: Calculations can results temporarily in larger MPIs. So the number
* of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher.
*/
#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
#endif /* !MBEDTLS_MPI_MAX_SIZE */
#define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
/*
* When reading from files with mbedtls_mpi_read_file() and writing to files with
* mbedtls_mpi_write_file() the buffer should have space
* for a (short) label, the MPI (in the provided radix), the newline
* characters and the '\0'.
*
* By default we assume at least a 10 char label, a minimum radix of 10
* (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
* Autosized at compile time for at least a 10 char label, a minimum radix
* of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size.
*
* This used to be statically sized to 1250 for a maximum of 4096 bit
* numbers (1234 decimal chars).
*
* Calculate using the formula:
* MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) +
* LabelSize + 6
*/
#define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS )
#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332
#define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 )
/*
* Define the base integer type, architecture-wise.
*
* 32 or 64-bit integer types can be forced regardless of the underlying
* architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64
* respectively and undefining MBEDTLS_HAVE_ASM.
*
* Double-width integers (e.g. 128-bit in 64-bit architectures) can be
* disabled by defining MBEDTLS_NO_UDBL_DIVISION.
*/
#if !defined(MBEDTLS_HAVE_INT32)
#if defined(_MSC_VER) && defined(_M_AMD64)
/* Always choose 64-bit when using MSC */
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#elif defined(__GNUC__) && ( \
defined(__amd64__) || defined(__x86_64__) || \
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
( defined(__sparc__) && defined(__arch64__) ) || \
defined(__s390x__) || defined(__mips64) )
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#elif defined(__ARMCC_VERSION) && defined(__aarch64__)
/*
* __ARMCC_VERSION is defined for both armcc and armclang and
* __aarch64__ is only defined by armclang when compiling 64-bit code
*/
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* !MBEDTLS_HAVE_INT64 */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef __uint128_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#elif defined(MBEDTLS_HAVE_INT64)
/* Force 64-bit integers with unknown compiler */
typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint;
#endif
#endif /* !MBEDTLS_HAVE_INT32 */
#if !defined(MBEDTLS_HAVE_INT64)
/* Default to 32-bit compilation */
#if !defined(MBEDTLS_HAVE_INT32)
#define MBEDTLS_HAVE_INT32
#endif /* !MBEDTLS_HAVE_INT32 */
typedef int32_t mbedtls_mpi_sint;
typedef uint32_t mbedtls_mpi_uint;
#if !defined(MBEDTLS_NO_UDBL_DIVISION)
typedef uint64_t mbedtls_t_udbl;
#define MBEDTLS_HAVE_UDBL
#endif /* !MBEDTLS_NO_UDBL_DIVISION */
#endif /* !MBEDTLS_HAVE_INT64 */
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief MPI structure
*/
typedef struct
{
int s; /*!< integer sign */
size_t n; /*!< total # of limbs */
mbedtls_mpi_uint *p; /*!< pointer to limbs */
}
mbedtls_mpi;
/**
* \brief Initialize one MPI (make internal references valid)
* This just makes it ready to be set or freed,
* but does not define a value for the MPI.
*
* \param X One MPI to initialize.
*/
void mbedtls_mpi_init( mbedtls_mpi *X );
/**
* \brief Unallocate one MPI
*
* \param X One MPI to unallocate.
*/
void mbedtls_mpi_free( mbedtls_mpi *X );
/**
* \brief Enlarge to the specified number of limbs
*
* \param X MPI to grow
* \param nblimbs The target number of limbs
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief Resize down, keeping at least the specified number of limbs
*
* \param X MPI to shrink
* \param nblimbs The minimum number of limbs to keep
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs );
/**
* \brief Copy the contents of Y into X
*
* \param X Destination MPI
* \param Y Source MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Swap the contents of X and Y
*
* \param X First MPI value
* \param Y Second MPI value
*/
void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y );
/**
* \brief Safe conditional assignement X = Y if assign is 1
*
* \param X MPI to conditionally assign to
* \param Y Value to be assigned
* \param assign 1: perform the assignment, 0: keep X's original value
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_copy( X, Y );
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*/
int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Safe conditional swap X <-> Y if swap is 1
*
* \param X First mbedtls_mpi value
* \param Y Second mbedtls_mpi value
* \param assign 1: perform the swap, 0: keep X and Y's original values
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
*
* \note This function is equivalent to
* if( assign ) mbedtls_mpi_swap( X, Y );
* except that it avoids leaking any information about whether
* the assignment was done or not (the above code may leak
* information through branch prediction and/or memory access
* patterns analysis).
*/
int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign );
/**
* \brief Set value from integer
*
* \param X MPI to set
* \param z Value to use
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Get a specific bit from X
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
*
* \return Either a 0 or a 1
*/
int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos );
/**
* \brief Set a bit of X to a specific value of 0 or 1
*
* \note Will grow X if necessary to set a bit to 1 in a not yet
* existing limb. Will not grow if bit should be set to 0
*
* \param X MPI to use
* \param pos Zero-based index of the bit in X
* \param val The value to set the bit to (0 or 1)
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
*/
int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val );
/**
* \brief Return the number of zero-bits before the least significant
* '1' bit
*
* Note: Thus also the zero-based index of the least significant '1' bit
*
* \param X MPI to use
*/
size_t mbedtls_mpi_lsb( const mbedtls_mpi *X );
/**
* \brief Return the number of bits up to and including the most
* significant '1' bit'
*
* Note: Thus also the one-based index of the most significant '1' bit
*
* \param X MPI to use
*/
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X );
/**
* \brief Return the total size in bytes
*
* \param X MPI to use
*/
size_t mbedtls_mpi_size( const mbedtls_mpi *X );
/**
* \brief Import from an ASCII string
*
* \param X Destination MPI
* \param radix Input numeric base
* \param s Null-terminated string buffer
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s );
/**
* \brief Export into an ASCII string
*
* \param X Source MPI
* \param radix Output numeric base
* \param buf Buffer to write the string to
* \param buflen Length of buf
* \param olen Length of the string written, including final NUL byte
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* \note Call this function with buflen = 0 to obtain the
* minimum required buffer size in *olen.
*/
int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
char *buf, size_t buflen, size_t *olen );
#if defined(MBEDTLS_FS_IO)
/**
* \brief Read MPI from a line in an opened file
*
* \param X Destination MPI
* \param radix Input numeric base
* \param fin Input file handle
*
* \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if
* the file read buffer is too small or a
* MBEDTLS_ERR_MPI_XXX error code
*
* \note On success, this function advances the file stream
* to the end of the current line or to EOF.
*
* The function returns 0 on an empty line.
*
* Leading whitespaces are ignored, as is a
* '0x' prefix for radix 16.
*
*/
int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin );
/**
* \brief Write X into an opened file, or stdout if fout is NULL
*
* \param p Prefix, can be NULL
* \param X Source MPI
* \param radix Output numeric base
* \param fout Output file handle (can be NULL)
*
* \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code
*
* \note Set fout == NULL to print X on the console.
*/
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout );
#endif /* MBEDTLS_FS_IO */
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
/**
* \brief Export X into unsigned binary data, big endian.
* Always fills the whole buffer, which will start with zeros
* if the number is smaller.
*
* \param X Source MPI
* \param buf Output buffer
* \param buflen Output buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen );
/**
* \brief Left-shift: X <<= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count );
/**
* \brief Right-shift: X >>= count
*
* \param X MPI to shift
* \param count Amount to shift
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count );
/**
* \brief Compare unsigned values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if |X| is greater than |Y|,
* -1 if |X| is lesser than |Y| or
* 0 if |X| is equal to |Y|
*/
int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param Y Right-hand MPI
*
* \return 1 if X is greater than Y,
* -1 if X is lesser than Y or
* 0 if X is equal to Y
*/
int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y );
/**
* \brief Compare signed values
*
* \param X Left-hand MPI
* \param z The integer value to compare to
*
* \return 1 if X is greater than z,
* -1 if X is lesser than z or
* 0 if X is equal to z
*/
int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z );
/**
* \brief Unsigned addition: X = |A| + |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Unsigned subtraction: X = |A| - |B|
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed addition: X = A + B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed subtraction: X = A - B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Signed addition: X = A + b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to add
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Signed subtraction: X = A - b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The integer value to subtract
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Baseline multiplication: X = A * B
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Baseline multiplication: X = A * b
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param b The unsigned integer value to multiply with
*
* \note b is unsigned
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b );
/**
* \brief Division by mbedtls_mpi: A = Q * B + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0
*
* \note Either Q or R can be NULL.
*/
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Division by int: A = Q * b + R
*
* \param Q Destination MPI for the quotient
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0
*
* \note Either Q or R can be NULL.
*/
int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Modulo: R = A mod B
*
* \param R Destination MPI for the rest value
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0
*/
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Modulo: r = A mod b
*
* \param r Destination mbedtls_mpi_uint
* \param A Left-hand MPI
* \param b Integer to divide by
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0,
* MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0
*/
int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b );
/**
* \brief Sliding-window exponentiation: X = A^E mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param E Exponent MPI
* \param N Modular MPI
* \param _RR Speed-up MPI used for recalculations
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or
* if E is negative
*
* \note _RR is used to avoid re-computing R*R mod N across
* multiple calls, which speeds up things a bit. It can
* be set to NULL if the extra performance is unneeded.
*/
int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR );
/**
* \brief Fill an MPI X with size bytes of random
*
* \param X Destination MPI
* \param size Size in bytes
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Greatest common divisor: G = gcd(A, B)
*
* \param G Destination MPI
* \param A Left-hand MPI
* \param B Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B );
/**
* \brief Modular inverse: X = A^-1 mod N
*
* \param X Destination MPI
* \param A Left-hand MPI
* \param N Right-hand MPI
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1,
MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N.
*/
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N );
/**
* \brief Miller-Rabin primality test
*
* \param X MPI to check
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime
*/
int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Prime number generation
*
* \param X Destination MPI
* \param nbits Required size of X in bits
* ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS )
* \param dh_flag If 1, then (X-1)/2 will be prime too
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful (probably prime),
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
*/
int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if the test failed
*/
int mbedtls_mpi_self_test( int verbose );
#ifdef __cplusplus
}
#endif
#endif /* bignum.h */

View File

@ -1,887 +0,0 @@
/**
* \file bn_mul.h
*
* \brief Multi-precision integer library
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Multiply source vector [s] with b, add result
* to destination vector [d] and set carry c.
*
* Currently supports:
*
* . IA-32 (386+) . AMD64 / EM64T
* . IA-32 (SSE2) . Motorola 68000
* . PowerPC, 32-bit . MicroBlaze
* . PowerPC, 64-bit . TriCore
* . SPARC v8 . ARM v3+
* . Alpha . MIPS32
* . C, longlong . C, generic
*/
#ifndef MBEDTLS_BN_MUL_H
#define MBEDTLS_BN_MUL_H
#include "bignum.h"
#if defined(MBEDTLS_HAVE_ASM)
#ifndef asm
#define asm __asm
#endif
/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
#if defined(__GNUC__) && \
( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
#if defined(__i386__)
#define MULADDC_INIT \
asm( \
"movl %%ebx, %0 \n\t" \
"movl %5, %%esi \n\t" \
"movl %6, %%edi \n\t" \
"movl %7, %%ecx \n\t" \
"movl %8, %%ebx \n\t"
#define MULADDC_CORE \
"lodsl \n\t" \
"mull %%ebx \n\t" \
"addl %%ecx, %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"addl (%%edi), %%eax \n\t" \
"adcl $0, %%edx \n\t" \
"movl %%edx, %%ecx \n\t" \
"stosl \n\t"
#if defined(MBEDTLS_HAVE_SSE2)
#define MULADDC_HUIT \
"movd %%ecx, %%mm1 \n\t" \
"movd %%ebx, %%mm0 \n\t" \
"movd (%%edi), %%mm3 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd (%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"movd 4(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"movd 8(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd 12(%%esi), %%mm7 \n\t" \
"pmuludq %%mm0, %%mm7 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 4(%%edi), %%mm3 \n\t" \
"paddq %%mm4, %%mm3 \n\t" \
"movd 8(%%edi), %%mm5 \n\t" \
"paddq %%mm6, %%mm5 \n\t" \
"movd 12(%%edi), %%mm4 \n\t" \
"paddq %%mm4, %%mm7 \n\t" \
"movd %%mm1, (%%edi) \n\t" \
"movd 16(%%esi), %%mm2 \n\t" \
"pmuludq %%mm0, %%mm2 \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 20(%%esi), %%mm4 \n\t" \
"pmuludq %%mm0, %%mm4 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd 24(%%esi), %%mm6 \n\t" \
"pmuludq %%mm0, %%mm6 \n\t" \
"movd %%mm1, 4(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd 28(%%esi), %%mm3 \n\t" \
"pmuludq %%mm0, %%mm3 \n\t" \
"paddq %%mm5, %%mm1 \n\t" \
"movd 16(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm2 \n\t" \
"movd %%mm1, 8(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm7, %%mm1 \n\t" \
"movd 20(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm4 \n\t" \
"movd %%mm1, 12(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm2, %%mm1 \n\t" \
"movd 24(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm6 \n\t" \
"movd %%mm1, 16(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm4, %%mm1 \n\t" \
"movd 28(%%edi), %%mm5 \n\t" \
"paddq %%mm5, %%mm3 \n\t" \
"movd %%mm1, 20(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm6, %%mm1 \n\t" \
"movd %%mm1, 24(%%edi) \n\t" \
"psrlq $32, %%mm1 \n\t" \
"paddq %%mm3, %%mm1 \n\t" \
"movd %%mm1, 28(%%edi) \n\t" \
"addl $32, %%edi \n\t" \
"addl $32, %%esi \n\t" \
"psrlq $32, %%mm1 \n\t" \
"movd %%mm1, %%ecx \n\t"
#define MULADDC_STOP \
"emms \n\t" \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#else
#define MULADDC_STOP \
"movl %4, %%ebx \n\t" \
"movl %%ecx, %1 \n\t" \
"movl %%edi, %2 \n\t" \
"movl %%esi, %3 \n\t" \
: "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
: "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
: "eax", "ecx", "edx", "esi", "edi" \
);
#endif /* SSE2 */
#endif /* i386 */
#if defined(__amd64__) || defined (__x86_64__)
#define MULADDC_INIT \
asm( \
"xorq %%r8, %%r8 \n\t"
#define MULADDC_CORE \
"movq (%%rsi), %%rax \n\t" \
"mulq %%rbx \n\t" \
"addq $8, %%rsi \n\t" \
"addq %%rcx, %%rax \n\t" \
"movq %%r8, %%rcx \n\t" \
"adcq $0, %%rdx \n\t" \
"nop \n\t" \
"addq %%rax, (%%rdi) \n\t" \
"adcq %%rdx, %%rcx \n\t" \
"addq $8, %%rdi \n\t"
#define MULADDC_STOP \
: "+c" (c), "+D" (d), "+S" (s) \
: "b" (b) \
: "rax", "rdx", "r8" \
);
#endif /* AMD64 */
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
asm( \
"movl %3, %%a2 \n\t" \
"movl %4, %%a3 \n\t" \
"movl %5, %%d3 \n\t" \
"movl %6, %%d2 \n\t" \
"moveq #0, %%d0 \n\t"
#define MULADDC_CORE \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"moveq #0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d4, %%d3 \n\t"
#define MULADDC_STOP \
"movl %%d3, %0 \n\t" \
"movl %%a3, %1 \n\t" \
"movl %%a2, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
);
#define MULADDC_HUIT \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d4:%%d1 \n\t" \
"addxl %%d3, %%d1 \n\t" \
"addxl %%d0, %%d4 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"movel %%a2@+, %%d1 \n\t" \
"mulul %%d2, %%d3:%%d1 \n\t" \
"addxl %%d4, %%d1 \n\t" \
"addxl %%d0, %%d3 \n\t" \
"addl %%d1, %%a3@+ \n\t" \
"addxl %%d0, %%d3 \n\t"
#endif /* MC68000 */
#if defined(__powerpc64__) || defined(__ppc64__)
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"ld r3, %3 \n\t" \
"ld r4, %4 \n\t" \
"ld r5, %5 \n\t" \
"ld r6, %6 \n\t" \
"addi r3, r3, -8 \n\t" \
"addi r4, r4, -8 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"ldu r7, 8(r3) \n\t" \
"mulld r8, r7, r6 \n\t" \
"mulhdu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"ld r7, 8(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stdu r8, 8(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 8 \n\t" \
"addi r3, r3, 8 \n\t" \
"std r5, %0 \n\t" \
"std r4, %1 \n\t" \
"std r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"ld %%r3, %3 \n\t" \
"ld %%r4, %4 \n\t" \
"ld %%r5, %5 \n\t" \
"ld %%r6, %6 \n\t" \
"addi %%r3, %%r3, -8 \n\t" \
"addi %%r4, %%r4, -8 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"ldu %%r7, 8(%%r3) \n\t" \
"mulld %%r8, %%r7, %%r6 \n\t" \
"mulhdu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"ld %%r7, 8(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stdu %%r8, 8(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 8 \n\t" \
"addi %%r3, %%r3, 8 \n\t" \
"std %%r5, %0 \n\t" \
"std %%r4, %1 \n\t" \
"std %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
#if defined(__MACH__) && defined(__APPLE__)
#define MULADDC_INIT \
asm( \
"lwz r3, %3 \n\t" \
"lwz r4, %4 \n\t" \
"lwz r5, %5 \n\t" \
"lwz r6, %6 \n\t" \
"addi r3, r3, -4 \n\t" \
"addi r4, r4, -4 \n\t" \
"addic r5, r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu r7, 4(r3) \n\t" \
"mullw r8, r7, r6 \n\t" \
"mulhwu r9, r7, r6 \n\t" \
"adde r8, r8, r5 \n\t" \
"lwz r7, 4(r4) \n\t" \
"addze r5, r9 \n\t" \
"addc r8, r8, r7 \n\t" \
"stwu r8, 4(r4) \n\t"
#define MULADDC_STOP \
"addze r5, r5 \n\t" \
"addi r4, r4, 4 \n\t" \
"addi r3, r3, 4 \n\t" \
"stw r5, %0 \n\t" \
"stw r4, %1 \n\t" \
"stw r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#else /* __MACH__ && __APPLE__ */
#define MULADDC_INIT \
asm( \
"lwz %%r3, %3 \n\t" \
"lwz %%r4, %4 \n\t" \
"lwz %%r5, %5 \n\t" \
"lwz %%r6, %6 \n\t" \
"addi %%r3, %%r3, -4 \n\t" \
"addi %%r4, %%r4, -4 \n\t" \
"addic %%r5, %%r5, 0 \n\t"
#define MULADDC_CORE \
"lwzu %%r7, 4(%%r3) \n\t" \
"mullw %%r8, %%r7, %%r6 \n\t" \
"mulhwu %%r9, %%r7, %%r6 \n\t" \
"adde %%r8, %%r8, %%r5 \n\t" \
"lwz %%r7, 4(%%r4) \n\t" \
"addze %%r5, %%r9 \n\t" \
"addc %%r8, %%r8, %%r7 \n\t" \
"stwu %%r8, 4(%%r4) \n\t"
#define MULADDC_STOP \
"addze %%r5, %%r5 \n\t" \
"addi %%r4, %%r4, 4 \n\t" \
"addi %%r3, %%r3, 4 \n\t" \
"stw %%r5, %0 \n\t" \
"stw %%r4, %1 \n\t" \
"stw %%r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
);
#endif /* __MACH__ && __APPLE__ */
#endif /* PPC32 */
/*
* The Sparc(64) assembly is reported to be broken.
* Disable it for now, until we're able to fix it.
*/
#if 0 && defined(__sparc__)
#if defined(__sparc64__)
#define MULADDC_INIT \
asm( \
"ldx %3, %%o0 \n\t" \
"ldx %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"stx %%o1, %1 \n\t" \
"stx %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#else /* __sparc64__ */
#define MULADDC_INIT \
asm( \
"ld %3, %%o0 \n\t" \
"ld %4, %%o1 \n\t" \
"ld %5, %%o2 \n\t" \
"ld %6, %%o3 \n\t"
#define MULADDC_CORE \
"ld [%%o0], %%o4 \n\t" \
"inc 4, %%o0 \n\t" \
"ld [%%o1], %%o5 \n\t" \
"umul %%o3, %%o4, %%o4 \n\t" \
"addcc %%o4, %%o2, %%o4 \n\t" \
"rd %%y, %%g1 \n\t" \
"addx %%g1, 0, %%g1 \n\t" \
"addcc %%o4, %%o5, %%o4 \n\t" \
"st %%o4, [%%o1] \n\t" \
"addx %%g1, 0, %%o2 \n\t" \
"inc 4, %%o1 \n\t"
#define MULADDC_STOP \
"st %%o2, %0 \n\t" \
"st %%o1, %1 \n\t" \
"st %%o0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \
);
#endif /* __sparc64__ */
#endif /* __sparc__ */
#if defined(__microblaze__) || defined(microblaze)
#define MULADDC_INIT \
asm( \
"lwi r3, %3 \n\t" \
"lwi r4, %4 \n\t" \
"lwi r5, %5 \n\t" \
"lwi r6, %6 \n\t" \
"andi r7, r6, 0xffff \n\t" \
"bsrli r6, r6, 16 \n\t"
#define MULADDC_CORE \
"lhui r8, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"lhui r9, r3, 0 \n\t" \
"addi r3, r3, 2 \n\t" \
"mul r10, r9, r6 \n\t" \
"mul r11, r8, r7 \n\t" \
"mul r12, r9, r7 \n\t" \
"mul r13, r8, r6 \n\t" \
"bsrli r8, r10, 16 \n\t" \
"bsrli r9, r11, 16 \n\t" \
"add r13, r13, r8 \n\t" \
"add r13, r13, r9 \n\t" \
"bslli r10, r10, 16 \n\t" \
"bslli r11, r11, 16 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r11 \n\t" \
"addc r13, r13, r0 \n\t" \
"lwi r10, r4, 0 \n\t" \
"add r12, r12, r10 \n\t" \
"addc r13, r13, r0 \n\t" \
"add r12, r12, r5 \n\t" \
"addc r5, r13, r0 \n\t" \
"swi r12, r4, 0 \n\t" \
"addi r4, r4, 4 \n\t"
#define MULADDC_STOP \
"swi r5, %0 \n\t" \
"swi r4, %1 \n\t" \
"swi r3, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r3", "r4" "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "r12", "r13" \
);
#endif /* MicroBlaze */
#if defined(__tricore__)
#define MULADDC_INIT \
asm( \
"ld.a %%a2, %3 \n\t" \
"ld.a %%a3, %4 \n\t" \
"ld.w %%d4, %5 \n\t" \
"ld.w %%d1, %6 \n\t" \
"xor %%d5, %%d5 \n\t"
#define MULADDC_CORE \
"ld.w %%d0, [%%a2+] \n\t" \
"madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
"ld.w %%d0, [%%a3] \n\t" \
"addx %%d2, %%d2, %%d0 \n\t" \
"addc %%d3, %%d3, 0 \n\t" \
"mov %%d4, %%d3 \n\t" \
"st.w [%%a3+], %%d2 \n\t"
#define MULADDC_STOP \
"st.w %0, %%d4 \n\t" \
"st.a %1, %%a3 \n\t" \
"st.a %2, %%a2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "d0", "d1", "e2", "d4", "a2", "a3" \
);
#endif /* TriCore */
/*
* gcc -O0 by default uses r7 for the frame pointer, so it complains about our
* use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately,
* passing that option is not easy when building with yotta.
*
* On the other hand, -fomit-frame-pointer is implied by any -Ox options with
* x !=0, which we can detect using __OPTIMIZE__ (which is also defined by
* clang and armcc5 under the same conditions).
*
* So, only use the optimized assembly below for optimized build, which avoids
* the build error and is pretty reasonable anyway.
*/
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
#define MULADDC_CANNOT_USE_R7
#endif
#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7)
#if defined(__thumb__) && !defined(__thumb2__)
#pragma message "using ARM THUMB MULADDC"
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t" \
"lsr r7, r3, #16 \n\t" \
"mov r9, r7 \n\t" \
"lsl r7, r3, #16 \n\t" \
"lsr r7, r7, #16 \n\t" \
"mov r8, r7 \n\t"
#define MULADDC_CORE \
"ldmia r0!, {r6} \n\t" \
"lsr r7, r6, #16 \n\t" \
"lsl r6, r6, #16 \n\t" \
"lsr r6, r6, #16 \n\t" \
"mov r4, r8 \n\t" \
"mul r4, r6 \n\t" \
"mov r3, r9 \n\t" \
"mul r6, r3 \n\t" \
"mov r5, r9 \n\t" \
"mul r5, r7 \n\t" \
"mov r3, r8 \n\t" \
"mul r7, r3 \n\t" \
"lsr r3, r6, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"lsr r3, r7, #16 \n\t" \
"add r5, r5, r3 \n\t" \
"add r4, r4, r2 \n\t" \
"mov r2, #0 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r6, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"lsl r3, r7, #16 \n\t" \
"add r4, r4, r3 \n\t" \
"adc r5, r2 \n\t" \
"ldr r3, [r1] \n\t" \
"add r4, r4, r3 \n\t" \
"adc r2, r5 \n\t" \
"stmia r1!, {r4} \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "r8", "r9", "cc" \
);
#else
#define MULADDC_INIT \
asm( \
"ldr r0, %3 \n\t" \
"ldr r1, %4 \n\t" \
"ldr r2, %5 \n\t" \
"ldr r3, %6 \n\t"
#define MULADDC_CORE \
"ldr r4, [r0], #4 \n\t" \
"mov r5, #0 \n\t" \
"ldr r6, [r1] \n\t" \
"umlal r2, r5, r3, r4 \n\t" \
"adds r7, r6, r2 \n\t" \
"adc r2, r5, #0 \n\t" \
"str r7, [r1], #4 \n\t"
#define MULADDC_STOP \
"str r2, %0 \n\t" \
"str r1, %1 \n\t" \
"str r0, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "r0", "r1", "r2", "r3", "r4", "r5", \
"r6", "r7", "cc" \
);
#endif /* Thumb */
#endif /* ARMv3 */
#if defined(__alpha__)
#define MULADDC_INIT \
asm( \
"ldq $1, %3 \n\t" \
"ldq $2, %4 \n\t" \
"ldq $3, %5 \n\t" \
"ldq $4, %6 \n\t"
#define MULADDC_CORE \
"ldq $6, 0($1) \n\t" \
"addq $1, 8, $1 \n\t" \
"mulq $6, $4, $7 \n\t" \
"umulh $6, $4, $6 \n\t" \
"addq $7, $3, $7 \n\t" \
"cmpult $7, $3, $3 \n\t" \
"ldq $5, 0($2) \n\t" \
"addq $7, $5, $7 \n\t" \
"cmpult $7, $5, $5 \n\t" \
"stq $7, 0($2) \n\t" \
"addq $2, 8, $2 \n\t" \
"addq $6, $3, $3 \n\t" \
"addq $5, $3, $3 \n\t"
#define MULADDC_STOP \
"stq $3, %0 \n\t" \
"stq $2, %1 \n\t" \
"stq $1, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
);
#endif /* Alpha */
#if defined(__mips__) && !defined(__mips64)
#define MULADDC_INIT \
asm( \
"lw $10, %3 \n\t" \
"lw $11, %4 \n\t" \
"lw $12, %5 \n\t" \
"lw $13, %6 \n\t"
#define MULADDC_CORE \
"lw $14, 0($10) \n\t" \
"multu $13, $14 \n\t" \
"addi $10, $10, 4 \n\t" \
"mflo $14 \n\t" \
"mfhi $9 \n\t" \
"addu $14, $12, $14 \n\t" \
"lw $15, 0($11) \n\t" \
"sltu $12, $14, $12 \n\t" \
"addu $15, $14, $15 \n\t" \
"sltu $14, $15, $14 \n\t" \
"addu $12, $12, $9 \n\t" \
"sw $15, 0($11) \n\t" \
"addu $12, $12, $14 \n\t" \
"addi $11, $11, 4 \n\t"
#define MULADDC_STOP \
"sw $12, %0 \n\t" \
"sw $11, %1 \n\t" \
"sw $10, %2 \n\t" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "$9", "$10", "$11", "$12", "$13", "$14", "$15" \
);
#endif /* MIPS */
#endif /* GNUC */
#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
#define MULADDC_INIT \
__asm mov esi, s \
__asm mov edi, d \
__asm mov ecx, c \
__asm mov ebx, b
#define MULADDC_CORE \
__asm lodsd \
__asm mul ebx \
__asm add eax, ecx \
__asm adc edx, 0 \
__asm add eax, [edi] \
__asm adc edx, 0 \
__asm mov ecx, edx \
__asm stosd
#if defined(MBEDTLS_HAVE_SSE2)
#define EMIT __asm _emit
#define MULADDC_HUIT \
EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
EMIT 0x0F EMIT 0x6E EMIT 0x1F \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x16 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
EMIT 0x0F EMIT 0x7E EMIT 0x0F \
EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
EMIT 0x0F EMIT 0x7E EMIT 0xC9
#define MULADDC_STOP \
EMIT 0x0F EMIT 0x77 \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#else
#define MULADDC_STOP \
__asm mov c, ecx \
__asm mov d, edi \
__asm mov s, esi \
#endif /* SSE2 */
#endif /* MSVC */
#endif /* MBEDTLS_HAVE_ASM */
#if !defined(MULADDC_CORE)
#if defined(MBEDTLS_HAVE_UDBL)
#define MULADDC_INIT \
{ \
mbedtls_t_udbl r; \
mbedtls_mpi_uint r0, r1;
#define MULADDC_CORE \
r = *(s++) * (mbedtls_t_udbl) b; \
r0 = (mbedtls_mpi_uint) r; \
r1 = (mbedtls_mpi_uint)( r >> biL ); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#else
#define MULADDC_INIT \
{ \
mbedtls_mpi_uint s0, s1, b0, b1; \
mbedtls_mpi_uint r0, r1, rx, ry; \
b0 = ( b << biH ) >> biH; \
b1 = ( b >> biH );
#define MULADDC_CORE \
s0 = ( *s << biH ) >> biH; \
s1 = ( *s >> biH ); s++; \
rx = s0 * b1; r0 = s0 * b0; \
ry = s1 * b0; r1 = s1 * b1; \
r1 += ( rx >> biH ); \
r1 += ( ry >> biH ); \
rx <<= biH; ry <<= biH; \
r0 += rx; r1 += (r0 < rx); \
r0 += ry; r1 += (r0 < ry); \
r0 += c; r1 += (r0 < c); \
r0 += *d; r1 += (r0 < *d); \
c = r1; *(d++) = r0;
#define MULADDC_STOP \
}
#endif /* C (generic) */
#endif /* C (longlong) */
#endif /* bn_mul.h */

View File

@ -1,4 +0,0 @@
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_HAVE_ASM

View File

@ -1,7 +0,0 @@
aes.c/.h rsa.c/.h are heavily modified/reduced
bignum.c/.h bn_mul.h only had some minor modifications:
headers location moved from mbedtls/ to .
disabled some unused functions by "#if 0 // unused"
ASCII I/O
everything below mbedtls_mpi_exp_mod

View File

@ -1,61 +0,0 @@
// mbedtls RSA public
// only the pubkey function for signatures verifying
// original rsa.c had too many extra functions not used and too many dependencies
#include <string.h>
#include "bignum.h"
#include "rsa.h"
void rsa_init(rsa_context_t *ctx) {
memset(ctx, 0, sizeof(rsa_context_t));
}
// I don't know why mbedtls doesn't provide this
// instead, all callers set N/E/len manually
// this could be seen in mbedtls_rsa_self_test(rsa.c), main(dh_client.c) and main(rsa_verify.c)
int rsa_set_pubkey(rsa_context_t *ctx, const unsigned char * n_buf, size_t n_len,
const unsigned char * e_buf, size_t e_len)
{
int ret0 = (mbedtls_mpi_read_binary(&ctx->N, n_buf, n_len));
int ret1 = (mbedtls_mpi_read_binary(&ctx->E, e_buf, e_len));
if (ret0 == 0 && ret1 == 0) {
ctx->len = (mbedtls_mpi_bitlen(&ctx->N) + 7) >> 3;
// we should check the key now to be safe?
// anyway usually we load known working keys, so it's omitted
return 0;
} else {
return ret0 || ret1;
}
}
// basically mbedtls_rsa_public
int rsa_public(rsa_context_t *ctx, const unsigned char *input, unsigned char *output) {
int ret;
size_t olen;
mbedtls_mpi T;
mbedtls_mpi_init(&T);
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&T, input, ctx->len));
if (mbedtls_mpi_cmp_mpi(&T, &ctx->N) >= 0)
{
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
goto cleanup;
}
olen = ctx->len;
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, &ctx->E, &ctx->N, &ctx->RN));
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen));
cleanup:
mbedtls_mpi_free(&T);
if (ret != 0)
return(MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret);
return(0);
}

View File

@ -1,18 +0,0 @@
#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
#include "bignum.h"
typedef struct {
size_t len;
mbedtls_mpi N;
mbedtls_mpi E;
mbedtls_mpi RN;
} rsa_context_t;
void rsa_init(rsa_context_t *rsa);
int rsa_set_pubkey(rsa_context_t *rsa, const unsigned char * n_buf, size_t n_len,
const unsigned char * e_buf, size_t e_len);
int rsa_public(rsa_context_t *rsa, const unsigned char *input, unsigned char *output);

View File

@ -1,323 +0,0 @@
#include <stdint.h>
#include "../mbedtls/aes.h"
#include "crypto.h"
//#include "ticket0.h"
#include "utils.h"
// more info:
// https://github.com/Jimmy-Z/TWLbf/blob/master/dsi.c
// https://github.com/Jimmy-Z/bfCL/blob/master/dsi.h
// ported back to 32 bit for ARM9
static const uint32_t DSi_NAND_KEY_Y[4] =
{0x0ab9dc76u, 0xbd4dc4d3u, 0x202ddd1du, 0xe1a00005u};
static const uint32_t DSi_ES_KEY_Y[4] =
{0x8b5acce5u, 0x72c9d056u, 0xdce8179cu, 0xa9361239u};
static const uint32_t DSi_BOOT2_KEY[4] =
{0x8080ee98u, 0xf6b46c00u, 0x626ec23au, 0xad34ecf9u};
static const uint32_t DSi_KEY_MAGIC[4] =
{0x1a4f3e79u, 0x2a680f5fu, 0x29590258u, 0xfffefb4eu};
static inline void xor_128(uint32_t *x, const uint32_t *a, const uint32_t *b){
x[0] = a[0] ^ b[0];
x[1] = a[1] ^ b[1];
x[2] = a[2] ^ b[2];
x[3] = a[3] ^ b[3];
}
static inline void add_128(uint32_t *a, const uint32_t *b){
unsigned c1, c2, c3; // carry
// round 1
a[3] += b[3];
a[2] += b[2];
a[1] += b[1];
a[0] += b[0];
// carry
c3 = a[2] < b[2];
c2 = a[1] < b[1];
c1 = a[0] < b[0];
// round 2
a[3] += c3;
a[2] += c2;
a[1] += c1;
// carry
c3 = a[2] < c2;
c2 = a[1] < c1;
// round 3
a[3] += c3;
a[2] += c2;
// carry
c3 = a[2] < c2;
// round 4
a[3] += c3;
}
static inline void add_128_32(uint32_t *a, uint32_t b){
a[0] += b;
if(a[0] < b){
a[1] += 1;
if (a[1] == 0) {
a[2] += 1;
if (a[2] == 0) {
a[3] += 1;
}
}
}
}
// Answer to life, universe and everything.
static inline void rol42_128(uint32_t *a){
uint32_t t3 = a[3], t2 = a[2];
a[3] = (a[2] << 10) | (a[1] >> 22);
a[2] = (a[1] << 10) | (a[0] >> 22);
a[1] = (a[0] << 10) | (t3 >> 22);
a[0] = (t3 << 10) | (t2 >> 22);
}
static void dsi_aes_set_key(uint32_t *rk, const uint32_t *console_id, key_mode_t mode) {
uint32_t key[4];
switch (mode) {
case NAND:
key[0] = console_id[0];
key[1] = console_id[0] ^ 0x24ee6906;
key[2] = console_id[1] ^ 0xe65b601d;
key[3] = console_id[1];
break;
case NAND_3DS:
key[0] = (console_id[0] ^ 0xb358a6af) | 0x80000000;
key[1] = 0x544e494e;
key[2] = 0x4f444e45;
key[3] = console_id[1] ^ 0x08c267b7;
break;
case ES:
key[0] = 0x4e00004a;
key[1] = 0x4a00004e;
key[2] = console_id[1] ^ 0xc80c4b72;
key[3] = console_id[0];
break;
default:
break;
}
// Key = ((Key_X XOR Key_Y) + FFFEFB4E295902582A680F5F1A4F3E79h) ROL 42
// equivalent to F_XY in twltool/f_xy.c
xor_128(key, key, mode == ES ? DSi_ES_KEY_Y : DSi_NAND_KEY_Y);
// iprintf("AES KEY: XOR KEY_Y:\n");
// print_bytes(key, 16);
add_128(key, DSi_KEY_MAGIC);
// iprintf("AES KEY: + MAGIC:\n");
// print_bytes(key, 16);
rol42_128(key);
// iprintf("AES KEY: ROL 42:\n");
// print_bytes(key, 16);
aes_set_key_enc_128_be(rk, (uint8_t*)key);
}
int dsi_sha1_verify(const void *digest_verify, const void *data, unsigned len) {
uint8_t digest[SHA1_LEN];
my_swiSHA1Calc(digest, data, len);
// return type of swiSHA1Verify() is declared void, so how exactly should we use it?
int ret = memcmp(digest, digest_verify, SHA1_LEN);
if (ret != 0) {
//printf(" ");
print_bytes(digest_verify, SHA1_LEN);
//printf("\n ");
print_bytes(digest, SHA1_LEN);
//printf("\n");
}
return ret;
}
static uint32_t nand_rk[RK_LEN];
static uint32_t nand_ctr_iv[4];
static uint32_t es_rk[RK_LEN];
static uint32_t boot2_rk[RK_LEN];
static int tables_generated = 0;
void dsi_crypt_init(const uint8_t *console_id_be, const uint8_t *emmc_cid, int is3DS) {
if (tables_generated == 0) {
aes_gen_tables();
tables_generated = 1;
}
uint32_t console_id[2];
GET_UINT32_BE(console_id[0], console_id_be, 4);
GET_UINT32_BE(console_id[1], console_id_be, 0);
dsi_aes_set_key(nand_rk, console_id, is3DS ? NAND_3DS : NAND);
dsi_aes_set_key(es_rk, console_id, ES);
aes_set_key_enc_128_be(boot2_rk, (uint8_t*)DSi_BOOT2_KEY);
uint32_t digest[SHA1_LEN / sizeof(uint32_t)];
my_swiSHA1Calc(digest, emmc_cid, 16);
nand_ctr_iv[0] = digest[0];
nand_ctr_iv[1] = digest[1];
nand_ctr_iv[2] = digest[2];
nand_ctr_iv[3] = digest[3];
}
static inline void aes_ctr(const uint32_t *rk, const uint32_t *ctr, uint32_t *in, uint32_t *out) {
uint32_t xor[4];
aes_encrypt_128_be(rk, (uint8_t*)ctr, (uint8_t*)xor);
xor_128(out, in, xor);
}
// crypt one block, in/out must be aligned to 32 bit(restriction induced by xor_128)
// offset as block offset, block as AES block
void dsi_nand_crypt_1(uint8_t* out, const uint8_t* in, uint32_t offset) {
uint32_t ctr[4] = { nand_ctr_iv[0], nand_ctr_iv[1], nand_ctr_iv[2], nand_ctr_iv[3] };
add_128_32(ctr, offset);
// iprintf("AES CTR:\n");
// print_bytes(buf, 16);
aes_ctr(nand_rk, ctr, (uint32_t*)in, (uint32_t*)out);
}
void dsi_nand_crypt(uint8_t* out, const uint8_t* in, uint32_t offset, unsigned count) {
uint32_t ctr[4] = { nand_ctr_iv[0], nand_ctr_iv[1], nand_ctr_iv[2], nand_ctr_iv[3] };
add_128_32(ctr, offset);
for (unsigned i = 0; i < count; ++i) {
aes_ctr(nand_rk, ctr, (uint32_t*)in, (uint32_t*)out);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
add_128_32(ctr, 1);
}
}
static uint32_t boot2_ctr[4];
void dsi_boot2_crypt_set_ctr(uint32_t size_r) {
boot2_ctr[0] = size_r;
boot2_ctr[1] = -size_r;
boot2_ctr[2] = ~size_r;
boot2_ctr[3] = 0;
}
void dsi_boot2_crypt(uint8_t* out, const uint8_t* in, unsigned count) {
for (unsigned i = 0; i < count; ++i) {
aes_ctr(boot2_rk, boot2_ctr, (uint32_t*)in, (uint32_t*)out);
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
add_128_32(boot2_ctr, 1);
}
}
// http://problemkaputt.de/gbatek.htm#dsiesblockencryption
// works in place, also must be aligned to 32 bit
// why is it called ES?
/*int dsi_es_block_crypt(uint8_t *buf, unsigned buf_len, crypt_mode_t mode) {
es_block_footer_t *footer;
footer = (es_block_footer_t*)(buf + buf_len - sizeof(es_block_footer_t));
// backup mac since it might be overwritten by padding
// and also nonce, it becomes garbage after decryption
uint8_t ccm_mac[AES_CCM_MAC_LEN];
uint8_t nonce[AES_CCM_NONCE_LEN];
memcpy(ccm_mac, footer->ccm_mac, AES_CCM_MAC_LEN);
memcpy(nonce, footer->nonce, AES_CCM_NONCE_LEN);
uint32_t ctr32[4], pad32[4], mac32[4];
// I'm too paranoid to use more stack variables
#define ctr ((uint8_t*)ctr32)
#define pad ((uint8_t*)pad32)
#define mac ((uint8_t*)mac32)
#define zero(a) static_assert(sizeof(a[0]) == 4, "invalid operand"); \
a[0] = 0; a[1] = 0; a[2] = 0; a[3] = 0
if (mode == DECRYPT) {
// decrypt footer
zero(ctr32);
memcpy(ctr + 1, nonce, AES_CCM_NONCE_LEN);
// footer might not be 32 bit aligned after all, so we copy it out to decrypt
memcpy(pad, footer->encrypted, AES_BLOCK_SIZE);
aes_ctr(es_rk, ctr32, pad32, pad32);
memcpy(footer->encrypted, pad, AES_BLOCK_SIZE);
}
// check decrypted footer
if (footer->fixed_3a != 0x3a) {
i//printff("ES block footer offset 0x10 should be 0x3a, got 0x%02x\n", footer->fixed_3a);
return 1;
}
uint32_t block_size;
GET_UINT32_BE(block_size, footer->len32be, 0);
block_size &= 0xffffff;
if (block_size + sizeof(es_block_footer_t) != buf_len) {
i//printff("block size in footer doesn't match, %06x != %06x\n",
(unsigned)block_size, (unsigned)(buf_len - sizeof(es_block_footer_t)));
return 1;
}
// padding to multiple of 16
uint32_t remainder = block_size & 0xf;
if (remainder != 0) {
zero(pad32);
if (mode == DECRYPT) {
ctr32[0] = (block_size >> 4) + 1;
memcpy(ctr + 3, nonce, AES_CCM_NONCE_LEN);
ctr[0xf] = 2;
aes_ctr(es_rk, ctr32, pad32, pad32);
}
memcpy(buf + block_size, pad + remainder, 16 - remainder);
block_size += 16 - remainder;
}
// AES-CCM MAC
mac32[0] = block_size;
memcpy(mac + 3, nonce, AES_CCM_NONCE_LEN);
mac[0xf] = 0x3a;
aes_encrypt_128_be(es_rk, mac, mac);
// AES-CCM CTR
ctr32[0] = 0;
memcpy(ctr + 3, nonce, AES_CCM_NONCE_LEN);
ctr[0xf] = 2;
// AES-CCM start
zero(pad32);
aes_ctr(es_rk, ctr32, pad32, pad32);
add_128_32(ctr32, 1);
// AES-CCM loop
if (mode == DECRYPT) {
for (unsigned i = 0; i < block_size; i += 16) {
aes_ctr(es_rk, ctr32, (uint32_t*)(buf + i), (uint32_t*)(buf + i));
add_128_32(ctr32, 1);
xor_128(mac32, mac32, (uint32_t*)(buf + i));
aes_encrypt_128_be(es_rk, mac, mac);
}
} else {
for (unsigned i = 0; i < block_size; i += 16) {
xor_128(mac32, mac32, (uint32_t*)(buf + i));
aes_encrypt_128_be(es_rk, mac, mac);
aes_ctr(es_rk, ctr32, (uint32_t*)(buf + i), (uint32_t*)(buf + i));
add_128_32(ctr32, 1);
}
}
// AES-CCM MAC final
xor_128(mac32, mac32, pad32);
if (mode == DECRYPT) {
if (memcmp(mac, ccm_mac, 16) == 0) {
if (remainder != 0) {
// restore mac
memcpy(footer->ccm_mac, ccm_mac, AES_CCM_MAC_LEN);
}
// restore nonce
memcpy(footer->nonce, nonce, AES_CCM_NONCE_LEN);
return 0;
} else {
//printf("MAC verification failed\n");
return 1;
}
} else {
memcpy(footer->ccm_mac, mac, AES_CCM_MAC_LEN);
// AES-CTR crypt later half of footer
zero(ctr32);
memcpy(ctr + 1, nonce, AES_CCM_NONCE_LEN);
memcpy(pad, footer->encrypted, AES_BLOCK_SIZE);
aes_ctr(es_rk, ctr32, pad32, pad32);
memcpy(footer->encrypted, pad, AES_BLOCK_SIZE);
// restore nonce
memcpy(footer->nonce, nonce, AES_CCM_NONCE_LEN);
return 0;
}
#undef ctr
#undef pad
#undef mac
#undef zero
}*/

View File

@ -1,35 +0,0 @@
#pragma once
#include <nds.h>
#define SHA1_LEN 20
#define AES_BLOCK_SIZE 16
typedef enum {
ENCRYPT,
DECRYPT
} crypt_mode_t;
typedef enum {
NAND,
NAND_3DS,
ES
} key_mode_t;
// don't want to include nds.h just for this
void my_swiSHA1Calc(void *digest, const void *buf, size_t len);
int dsi_sha1_verify(const void *digest_verify, const void *data, unsigned len);
void dsi_crypt_init(const uint8_t *console_id_be, const uint8_t *emmc_cid, int is3DS);
void dsi_nand_crypt_1(uint8_t *out, const uint8_t* in, u32 offset);
void dsi_nand_crypt(uint8_t *out, const uint8_t* in, u32 offset, unsigned count);
int dsi_es_block_crypt(uint8_t *buf, unsigned buf_len, crypt_mode_t mode);
void dsi_boot2_crypt_set_ctr(uint32_t size_r);
void dsi_boot2_crypt(uint8_t* out, const uint8_t* in, unsigned count);

View File

@ -31,7 +31,6 @@
#include "config.h"
#include "date.h"
#include "screenshot.h"
#include "dumpOperations.h"
#include "driveOperations.h"
#include "fileOperations.h"
#include "font.h"
@ -47,17 +46,10 @@ enum class DriveMenuOperation {
none,
sdCard,
flashcard,
ramDrive,
sysNand,
sysNandPhoto,
nitroFs,
fatImage,
gbaCart,
ndsCard,
fatImage
};
//static bool ramDumped = false;
bool flashcardMountSkipped = true;
static bool flashcardMountRan = true;
static int dmCursorPosition = 0;
@ -65,7 +57,6 @@ static std::vector<DriveMenuOperation> dmOperations;
char romTitle[2][13] = {0};
u32 romSize[2], romSizeTrimmed;
static u8 gbaFixedValue = 0;
static u8 stored_SCFG_MC = 0;
extern bool arm7SCFGLocked;
@ -82,55 +73,33 @@ void dm_drawTopScreen(void) {
if (dmOperations.size() == 0) {
font->print(firstCol, 1, true, STR_NO_DRIVES_FOUND, alignStart);
} else
for (int i = 0; i < (int)dmOperations.size(); i++) {
Palette pal = dmCursorPosition == i ? Palette::white : Palette::gray;
switch(dmOperations[i]) {
case DriveMenuOperation::sdCard:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_SDCARD_LABEL.c_str(), sdLabel[0] == 0 ? STR_UNTITLED.c_str() : sdLabel);
if(!driveWritable(Drive::sdCard))
} else {
for (int i = 0; i < (int)dmOperations.size(); i++) {
Palette pal = dmCursorPosition == i ? Palette::white : Palette::gray;
switch(dmOperations[i]) {
case DriveMenuOperation::sdCard:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_SDCARD_LABEL.c_str(), sdLabel[0] == 0 ? STR_UNTITLED.c_str() : sdLabel);
if(!driveWritable(Drive::sdCard))
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::flashcard:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_FLASHCARD_LABEL.c_str(), fatLabel[0] == 0 ? STR_UNTITLED.c_str() : fatLabel);
if(!driveWritable(Drive::flashcard))
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::nitroFs:
font->print(firstCol, i + 1, true, STR_NITROFS_LABEL, alignStart, pal);
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::flashcard:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_FLASHCARD_LABEL.c_str(), fatLabel[0] == 0 ? STR_UNTITLED.c_str() : fatLabel);
if(!driveWritable(Drive::flashcard))
break;
case DriveMenuOperation::fatImage:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel);
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::ramDrive:
font->print(firstCol, i + 1, true, STR_RAMDRIVE_LABEL, alignStart, pal);
break;
case DriveMenuOperation::sysNand:
font->print(firstCol, i + 1, true, STR_SYSNAND_LABEL, alignStart, pal);
if(!driveWritable(Drive::nand))
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::sysNandPhoto:
font->print(firstCol, i + 1, true, STR_SYSNAND_PHOTO_LABEL, alignStart, pal);
if(!driveWritable(Drive::nandPhoto))
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::nitroFs:
font->print(firstCol, i + 1, true, STR_NITROFS_LABEL, alignStart, pal);
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::fatImage:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel);
font->print(lastCol, i + 1, true, "[R]", alignEnd, pal);
break;
case DriveMenuOperation::gbaCart:
font->printf(firstCol, i + 1, true, alignStart, pal, STR_GBA_GAMECART.c_str(), romTitle[1]);
break;
case DriveMenuOperation::ndsCard:
if(romTitle[0][0] != 0)
font->printf(firstCol, i + 1, true, alignStart, pal, STR_NDS_GAMECARD.c_str(), romTitle[0]);
else
font->print(firstCol, i + 1, true, STR_NDS_GAMECARD_NO_TITLE, alignStart, pal);
break;
case DriveMenuOperation::none:
break;
break;
case DriveMenuOperation::none:
break;
}
}
}
font->update(true);
}
@ -159,8 +128,9 @@ void dm_drawBottomScreen(void) {
font->print(firstCol, row--, false, STR_SCREENSHOTTEXT, alignStart);
}
if(dmOperations[dmCursorPosition] == DriveMenuOperation::nitroFs || dmOperations[dmCursorPosition] == DriveMenuOperation::fatImage)
if(dmOperations[dmCursorPosition] == DriveMenuOperation::nitroFs || dmOperations[dmCursorPosition] == DriveMenuOperation::fatImage) {
font->print(firstCol, row--, false, STR_IMAGETEXT, alignStart);
}
font->print(firstCol, row--, false, titleName, alignStart);
switch(dmOperations[dmCursorPosition]) {
@ -174,37 +144,10 @@ void dm_drawBottomScreen(void) {
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_SLOT1_FAT.c_str(), getBytes(fatSize).c_str());
font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::flashcard)).c_str());
break;
case DriveMenuOperation::gbaCart:
font->printf(firstCol, 0, false, alignStart, Palette::white, STR_GBA_GAMECART.c_str(), romTitle[1]);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_GBA_GAME.c_str(), getBytes(romSize[1]).c_str());
break;
case DriveMenuOperation::nitroFs:
font->print(firstCol, 0, false, STR_NITROFS_LABEL, alignStart);
font->print(firstCol, 1, false, STR_GAME_VIRTUAL, alignStart);
break;
case DriveMenuOperation::ndsCard:
if(romTitle[0][0] != 0) {
font->printf(firstCol, 0, false, alignStart, Palette::white, STR_NDS_GAMECARD.c_str(), romTitle[0]);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_NDS_GAME.c_str(), getBytes(romSize[0]).c_str(), getBytes(romSizeTrimmed).c_str());
} else {
font->print(firstCol, 0, false, STR_NDS_GAMECARD_NO_TITLE, alignStart);
}
break;
case DriveMenuOperation::ramDrive:
font->print(firstCol, 0, false, STR_RAMDRIVE_LABEL, alignStart);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_RAMDRIVE_FAT.c_str(), getBytes(ramdSize).c_str());
font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::ramDrive)).c_str());
break;
case DriveMenuOperation::sysNand:
font->print(firstCol, 0, false, STR_SYSNAND_LABEL, alignStart);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(nandSize).c_str());
font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nand)).c_str());
break;
case DriveMenuOperation::sysNandPhoto:
font->print(firstCol, 0, false, STR_SYSNAND_LABEL, alignStart);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(photoSize).c_str());
font->printf(firstCol, 2, false, alignStart, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nandPhoto)).c_str());
break;
case DriveMenuOperation::fatImage:
font->printf(firstCol, 0, false, alignStart, Palette::white, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel);
font->printf(firstCol, 1, false, alignStart, Palette::white, STR_FAT_IMAGE.c_str(), getBytes(imgSize).c_str());
@ -222,66 +165,25 @@ void driveMenu (void) {
int held = 0;
while (true) {
if (!isDSiMode() && isRegularDS) {
gbaFixedValue = *(u8*)(0x080000B2);
}
dmOperations.clear();
if (sdMounted && !sdRemoved)
dmOperations.push_back(DriveMenuOperation::sdCard);
if (nandMounted)
dmOperations.push_back(DriveMenuOperation::sysNand);
if (photoMounted)
dmOperations.push_back(DriveMenuOperation::sysNandPhoto);
if (flashcardMounted && !driveRemoved(Drive::flashcard))
dmOperations.push_back(DriveMenuOperation::flashcard);
if (ramdriveMounted)
dmOperations.push_back(DriveMenuOperation::ramDrive);
if (imgMounted)
dmOperations.push_back(DriveMenuOperation::fatImage);
if (nitroMounted)
dmOperations.push_back(DriveMenuOperation::nitroFs);
if (!isDSiMode() && isRegularDS && gbaFixedValue == 0x96) {
dmOperations.push_back(DriveMenuOperation::gbaCart);
*(u16*)(0x020000C0) = 0;
if(romTitle[1][0] == 0) {
tonccpy(romTitle[1], (char*)0x080000A0, 12);
romSize[1] = 0;
for (romSize[1] = (1 << 20); romSize[1] < (1 << 25); romSize[1] <<= 1) {
vu16 *rompos = (vu16*)(0x08000000 + romSize[1]);
bool romend = true;
for (int j = 0; j < 0x1000; j++) {
if (rompos[j] != j) {
romend = false;
break;
}
}
if (romend)
break;
}
}
} else if (romTitle[1][0] != 0) {
if (romTitle[1][0] != 0) {
romTitle[1][0] = 0;
romSize[1] = 0;
}
if (((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || (isRegularDS && !flashcardMounted && romTitle[1][0] != 0))
|| (isDSiMode() && !arm7SCFGLocked && !(REG_SCFG_MC & BIT(0)))) {
dmOperations.push_back(DriveMenuOperation::ndsCard);
if(romTitle[0][0] == 0 && ((io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA) || !flashcardMounted) && !isRegularDS) {
sNDSHeaderExt ndsHeader;
cardInit(&ndsHeader);
tonccpy(romTitle[0], ndsHeader.gameTitle, 12);
romSize[0] = 0x20000 << ndsHeader.deviceSize;
romSizeTrimmed = (isDSiMode() && (ndsHeader.unitCode != 0) && (ndsHeader.twlRomSize > 0))
? ndsHeader.twlRomSize : ndsHeader.romSize + 0x88;
}
} else if (romTitle[0][0] != 0) {
if (romTitle[0][0] != 0) {
romTitle[0][0] = 0;
romSizeTrimmed = romSize[0] = 0;
}
if(dmCursorPosition >= (int)dmOperations.size())
dmCursorPosition = dmOperations.size() - 1;
if(dmCursorPosition >= (int)dmOperations.size())dmCursorPosition = dmOperations.size() - 1;
dm_drawBottomScreen();
dm_drawTopScreen();
@ -295,20 +197,8 @@ void driveMenu (void) {
held = keysHeld();
swiWaitForVBlank();
if (!isDSiMode() && isRegularDS) {
if (*(u8*)(0x080000B2) != gbaFixedValue) {
break;
}
if(ramdriveMounted && driveRemoved(Drive::ramDrive)) {
currentDrive = Drive::ramDrive;
chdir("ram:/");
ramdriveUnmount();
break;
}
} else if (isDSiMode()) {
if ((REG_SCFG_MC != stored_SCFG_MC) || (flashcardMounted && driveRemoved(Drive::flashcard))) {
break;
}
if (isDSiMode()) {
if ((REG_SCFG_MC != stored_SCFG_MC) || (flashcardMounted && driveRemoved(Drive::flashcard)))break;
if (sdMounted && sdRemoved) {
currentDrive = Drive::sdCard;
chdir("sd:/");
@ -349,14 +239,9 @@ void driveMenu (void) {
chdir("fat:/");
screenMode = 1;
break;
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::gbaCart && isRegularDS && flashcardMounted && gbaFixedValue == 0x96) {
gbaCartDump();
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::nitroFs && nitroMounted) {
if ((sdMounted && nitroCurrentDrive == Drive::sdCard)
|| (flashcardMounted && nitroCurrentDrive == Drive::flashcard)
|| (ramdriveMounted && nitroCurrentDrive == Drive::ramDrive)
|| (nandMounted && nitroCurrentDrive == Drive::nand)
|| (nandMounted && nitroCurrentDrive == Drive::nandPhoto)
|| (imgMounted && nitroCurrentDrive == Drive::fatImg))
{
currentDrive = Drive::nitroFS;
@ -364,30 +249,8 @@ void driveMenu (void) {
screenMode = 1;
break;
}
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::ndsCard && (sdMounted || flashcardMounted || romTitle[1][0] != 0)) {
ndsCardDump();
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::ramDrive && ramdriveMounted) {
currentDrive = Drive::ramDrive;
chdir("ram:/");
screenMode = 1;
break;
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::sysNand && nandMounted) {
currentDrive = Drive::nand;
chdir("nand:/");
screenMode = 1;
break;
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::sysNandPhoto && photoMounted) {
currentDrive = Drive::nandPhoto;
chdir("photo:/");
screenMode = 1;
break;
} else if (dmOperations[dmCursorPosition] == DriveMenuOperation::fatImage && imgMounted) {
if ((sdMounted && imgCurrentDrive == Drive::sdCard)
|| (flashcardMounted && imgCurrentDrive == Drive::flashcard)
|| (ramdriveMounted && imgCurrentDrive == Drive::ramDrive)
|| (nandMounted && imgCurrentDrive == Drive::nand)
|| (nandMounted && imgCurrentDrive == Drive::nandPhoto))
{
} if (dmOperations[dmCursorPosition] == DriveMenuOperation::fatImage && imgMounted) {
if ((sdMounted && imgCurrentDrive == Drive::sdCard) || (flashcardMounted && imgCurrentDrive == Drive::flashcard)) {
currentDrive = Drive::fatImg;
chdir("img:/");
screenMode = 1;
@ -428,9 +291,7 @@ void driveMenu (void) {
}
}
if (pressed & KEY_START) {
startMenu();
}
if (pressed & KEY_START)startMenu();
// Swap screens
if (pressed & config->screenSwapKey()) {
@ -439,9 +300,7 @@ void driveMenu (void) {
}
// Make a screenshot
if ((held & KEY_R) && (pressed & KEY_L)) {
screenshot();
}
if ((held & KEY_R) && (pressed & KEY_L))screenshot();
if (isDSiMode() && !flashcardMountSkipped) {
if (driveRemoved(Drive::flashcard)) {
@ -456,3 +315,4 @@ void driveMenu (void) {
}
}
}

View File

@ -11,18 +11,11 @@
#include "main.h"
#include "lzss.h"
#include "ramd.h"
#include "my_sd.h"
#include "nandio.h"
#include "imgio.h"
#include "tonccpy.h"
#include "language.h"
#include "sector0.h"
#include "io_m3_common.h"
#include "io_g6_common.h"
#include "io_sc_common.h"
#include "exptools.h"
#include "read_card.h"
@ -50,12 +43,10 @@ char sdLabel[12];
char fatLabel[12];
char imgLabel[12];
u32 nandSize = 0;
u32 photoSize = 0;
u64 sdSize = 0;
u64 fatSize = 0;
u64 imgSize = 0;
u32 ramdSize = 0;
const char* getDrivePath(void) {
switch (currentDrive) {
@ -63,12 +54,6 @@ const char* getDrivePath(void) {
return "sd:/";
case Drive::flashcard:
return "fat:/";
case Drive::ramDrive:
return "ram:/";
case Drive::nand:
return "nand:/";
case Drive::nandPhoto:
return "photo:/";
case Drive::nitroFS:
return "nitro:/";
case Drive::fatImg:
@ -82,18 +67,11 @@ Drive getDriveFromPath(const char *path) {
return Drive::sdCard;
} else if(strncmp(path, "fat:", 4) == 0) {
return Drive::flashcard;
} else if(strncmp(path, "ram:", 4)) {
return Drive::ramDrive;
} else if(strncmp(path, "nand:", 5)) {
return Drive::nand;
} else if(strncmp(path, "photo:", 6)) {
return Drive::nandPhoto;
} else if(strncmp(path, "nitro:", 6)) {
return Drive::nitroFS;
} else if(strncmp(path, "img:", 4)) {
return Drive::fatImg;
}
return currentDrive;
}
@ -106,10 +84,6 @@ void fixLabel(char* label) {
}
}
bool nandFound(void) {
return (access("nand:/", F_OK) == 0);
}
bool photoFound(void) {
return (access("photo:/", F_OK) == 0);
}
@ -134,39 +108,6 @@ bool imgFound(void) {
return (access("img:/", F_OK) == 0);
}
bool nandMount(void) {
fatMountSimple("nand", &io_dsi_nand);
if (nandFound()) {
struct statvfs st;
if (statvfs("nand:/", &st) == 0) {
nandSize = st.f_bsize * st.f_blocks;
nandMounted = true;
}
// Photo partition
/* mbr_t mbr;
io_dsi_nand.readSectors(0, 1, &mbr);
fatMount("photo", &io_dsi_nand, mbr.partitions[1].offset, 16, 8);
if (photoFound() && statvfs("photo:/", &st) == 0) {
photoSize = st.f_bsize * st.f_blocks;
photoMounted = true;
} */
}
return nandMounted /*&& photoMounted*/;
}
void nandUnmount(void) {
if(nandMounted)
fatUnmount("nand");
if(photoMounted)
fatUnmount("photo");
nandSize = 0;
nandMounted = false;
}
bool sdMount(void) {
fatMountSimple("sd", __my_io_dsisd());
if (sdFound()) {
@ -201,6 +142,39 @@ void sdUnmount(void) {
sdMounted = false;
}
DLDI_INTERFACE* dldiLoadFromBin (const u8 dldiAddr[]) {
// Check that it is a valid DLDI
if (!dldiIsValid ((DLDI_INTERFACE*)dldiAddr)) {
return NULL;
}
DLDI_INTERFACE* device = (DLDI_INTERFACE*)dldiAddr;
size_t dldiSize;
// Calculate actual size of DLDI
// Although the file may only go to the dldiEnd, the BSS section can extend past that
if (device->dldiEnd > device->bssEnd) {
dldiSize = (char*)device->dldiEnd - (char*)device->dldiStart;
} else {
dldiSize = (char*)device->bssEnd - (char*)device->dldiStart;
}
dldiSize = (dldiSize + 0x03) & ~0x03; // Round up to nearest integer multiple
// Clear unused space
toncset(device+dldiSize, 0, 0x4000-dldiSize);
dldiFixDriverAddresses (device);
if (device->ioInterface.features & FEATURE_SLOT_GBA) {
sysSetCartOwner(BUS_OWNER_ARM9);
}
if (device->ioInterface.features & FEATURE_SLOT_NDS) {
sysSetCardOwner(BUS_OWNER_ARM9);
}
return device;
}
const DISC_INTERFACE *dldiGet(void) {
if(io_dldi_data->ioInterface.features & FEATURE_SLOT_GBA)
sysSetCartOwner(BUS_OWNER_ARM9);
@ -267,87 +241,8 @@ void flashcardUnmount(void) {
flashcardMounted = false;
}
void ramdriveMount(bool ram32MB) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
ramdSectors = ram32MB ? 0xE000 : 0x6000;
fatMountSimple("ram", &io_ram_drive);
} else if (isRegularDS) {
ramdSectors = 0x8 + 0x4000;
ramdLocMep = (u8*)0x09000000;
if (*(u16*)(0x020000C0) != 0x334D && *(u16*)(0x020000C0) != 0x3647 && *(u16*)(0x020000C0) != 0x4353 && *(u16*)(0x020000C0) != 0x5A45) {
*(u16*)(0x020000C0) = 0; // Clear Slot-2 flashcard flag
}
if (*(u16*)(0x020000C0) == 0) {
*(vu16*)(0x08000000) = 0x4D54; // Write test
if (*(vu16*)(0x08000000) != 0x4D54) { // If not writeable
_M3_changeMode(M3_MODE_RAM); // Try again with M3
*(u16*)(0x020000C0) = 0x334D;
*(vu16*)(0x08000000) = 0x4D54;
}
if (*(vu16*)(0x08000000) != 0x4D54) {
_G6_SelectOperation(G6_MODE_RAM); // Try again with G6
*(u16*)(0x020000C0) = 0x3647;
*(vu16*)(0x08000000) = 0x4D54;
}
if (*(vu16*)(0x08000000) != 0x4D54) {
_SC_changeMode(SC_MODE_RAM); // Try again with SuperCard
*(u16*)(0x020000C0) = 0x4353;
*(vu16*)(0x08000000) = 0x4D54;
}
if (*(vu16*)(0x08000000) != 0x4D54) {
cExpansion::SetRompage(381); // Try again with EZ Flash
cExpansion::OpenNorWrite();
cExpansion::SetSerialMode();
*(u16*)(0x020000C0) = 0x5A45;
*(vu16*)(0x08000000) = 0x4D54;
}
if (*(vu16*)(0x08000000) != 0x4D54) {
*(u16*)(0x020000C0) = 0;
*(vu16*)(0x08240000) = 1; // Try again with Nintendo Memory Expansion Pak
}
}
if (*(u16*)(0x020000C0) == 0x334D || *(u16*)(0x020000C0) == 0x3647 || *(u16*)(0x020000C0) == 0x4353) {
ramdLocMep = (u8*)0x08000000;
ramdSectors = 0x8 + 0x10000;
} else if (*(u16*)(0x020000C0) == 0x5A45) {
ramdLocMep = (u8*)0x08000000;
ramdSectors = 0x8 + 0x8000;
}
if (*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1) {
fatMountSimple("ram", &io_ram_drive);
}
}
ramdriveMounted = (access("ram:/", F_OK) == 0);
if (ramdriveMounted) {
struct statvfs st;
if (statvfs("ram:/", &st) == 0) {
ramdSize = st.f_bsize * st.f_blocks;
}
}
}
void ramdriveUnmount(void) {
if(imgMounted && imgCurrentDrive == Drive::ramDrive)
imgUnmount();
if(nitroMounted && nitroCurrentDrive == Drive::ramDrive)
nitroUnmount();
fatUnmount("ram");
ramdSize = 0;
ramdriveMounted = false;
}
void nitroUnmount(void) {
if(imgMounted && imgCurrentDrive == Drive::nitroFS)
imgUnmount();
if(imgMounted && imgCurrentDrive == Drive::nitroFS)imgUnmount();
ownNitroFSMounted = 2;
nitroMounted = false;
}
@ -361,9 +256,7 @@ bool imgMount(const char* imgName, bool dsiwareSave) {
fatGetVolumeLabel("img", imgLabel);
fixLabel(imgLabel);
struct statvfs st;
if (statvfs("img:/", &st) == 0) {
imgSize = st.f_bsize * st.f_blocks;
}
if (statvfs("img:/", &st) == 0)imgSize = st.f_bsize * st.f_blocks;
return true;
}
return false;
@ -386,11 +279,6 @@ bool driveWritable(Drive drive) {
return __my_io_dsisd()->features & FEATURE_MEDIUM_CANWRITE;
case Drive::flashcard:
return dldiGet()->features & FEATURE_MEDIUM_CANWRITE;
case Drive::ramDrive:
return io_ram_drive.features & FEATURE_MEDIUM_CANWRITE;
case Drive::nand:
case Drive::nandPhoto:
return io_dsi_nand.features & FEATURE_MEDIUM_CANWRITE;
case Drive::nitroFS:
return false;
case Drive::fatImg:
@ -406,12 +294,6 @@ bool driveRemoved(Drive drive) {
return sdRemoved;
case Drive::flashcard:
return isDSiMode() ? REG_SCFG_MC & BIT(0) : !flashcardMounted;
case Drive::ramDrive:
return (isDSiMode() || REG_SCFG_EXT != 0) ? !ramdriveMounted : !(*(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1);
case Drive::nand:
return !nandMounted;
case Drive::nandPhoto:
return !photoMounted;
case Drive::nitroFS:
return driveRemoved(nitroCurrentDrive);
case Drive::fatImg:
@ -427,12 +309,6 @@ u64 driveSizeFree(Drive drive) {
return getBytesFree("sd:/");
case Drive::flashcard:
return getBytesFree("fat:/");
case Drive::ramDrive:
return getBytesFree("ram:/");
case Drive::nand:
return getBytesFree("nand:/");
case Drive::nandPhoto:
return getBytesFree("photo:/");
case Drive::nitroFS:
return 0;
case Drive::fatImg:

View File

@ -7,19 +7,14 @@
enum class Drive : u8 {
sdCard = 0,
flashcard,
ramDrive,
nand,
nandPhoto,
nitroFS,
fatImg
};
extern bool nandMounted;
extern bool photoMounted;
extern bool sdMounted;
extern bool sdMountedDone; // true if SD mount is successful once
extern bool flashcardMounted;
extern bool ramdriveMounted;
extern bool imgMounted;
extern bool nitroMounted;
@ -31,30 +26,21 @@ extern char sdLabel[12];
extern char fatLabel[12];
extern char imgLabel[12];
extern u32 nandSize;
extern u32 photoSize;
extern u64 sdSize;
extern u64 fatSize;
extern u64 imgSize;
extern u32 ramdSize;
extern const char* getDrivePath(void);
extern Drive getDriveFromPath(const char *path);
extern bool nandFound(void);
extern bool photoFound(void);
extern bool sdFound(void);
extern bool flashcardFound(void);
extern bool bothSDandFlashcard(void);
extern bool imgFound(void);
extern bool nandMount(void);
extern void nandUnmount(void);
extern bool sdMount(void);
extern void sdUnmount(void);
extern bool flashcardMount(void);
extern void flashcardUnmount(void);
extern void ramdriveMount(bool ram32MB);
extern void ramdriveUnmount(void);
extern void nitroUnmount(void);
extern bool imgMount(const char* imgName, bool dsiwareSave);
extern void imgUnmount(void);
@ -63,4 +49,6 @@ extern bool driveWritable(Drive drive);
extern bool driveRemoved(Drive drive);
extern u64 driveSizeFree(Drive drive);
#endif //FLASHCARD_H

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
#ifndef DUMPING_H
#define DUMPING_H
void ndsCardSaveRestore(const char *filename);
void gbaCartSaveRestore(const char *filename);
void ndsCardDump(void);
void gbaCartDump(void);
#endif //DUMPING_H

View File

@ -1,92 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdint.h>
#include "tonccpy.h"
//#define DEBUG
void n128_lrot(uint64_t *num, uint32_t shift)
{
uint64_t tmp[2];
tmp[0] = num[0]<<shift;
tmp[1] = num[1]<<shift;
tmp[0] |= (num[1]>>(64-shift));
tmp[1] |= (num[0]>>(64-shift));
num[0] = tmp[0];
num[1] = tmp[1];
}
void n128_rrot(uint64_t *num, uint32_t shift)
{
uint64_t tmp[2];
tmp[0] = num[0]>>shift;
tmp[1] = num[1]>>shift;
tmp[0] |= (num[1]<<(64-shift));
tmp[1] |= (num[0]<<(64-shift));
num[0] = tmp[0];
num[1] = tmp[1];
}
void n128_add(uint64_t *a, uint64_t *b)
{
uint64_t *a64 = a;
uint64_t *b64 = b;
uint64_t tmp = (a64[0]>>1)+(b64[0]>>1) + (a64[0] & b64[0] & 1);
tmp = tmp >> 63;
a64[0] = a64[0] + b64[0];
a64[1] = a64[1] + b64[1] + tmp;
}
void n128_sub(uint64_t *a, uint64_t *b)
{
uint64_t *a64 = a;
uint64_t *b64 = b;
uint64_t tmp = (a64[0]>>1)-(b64[0]>>1) - ((a64[0]>>63) & (b64[0]>>63) & 1);
tmp = tmp >> 63;
a64[0] = a64[0] - b64[0];
a64[1] = a64[1] - b64[1] - tmp;
}
void F_XY(uint32_t *key, uint32_t *key_x, uint32_t *key_y)
{
int i;
unsigned char key_xy[16];
toncset(key_xy, 0, 16);
toncset(key, 0, 16);
for(i=0; i<16; i++)key_xy[i] = ((unsigned char*)key_x)[i] ^ ((unsigned char*)key_y)[i];
key[0] = 0x1a4f3e79;
key[1] = 0x2a680f5f;
key[2] = 0x29590258;
key[3] = 0xfffefb4e;
n128_add((uint64_t*)key, (uint64_t*)key_xy);
n128_lrot((uint64_t*)key, 42);
}
//F_XY_reverse does the reverse of F(X^Y): takes (normal)key, and does F in reverse to generate the original X^Y key_xy.
void F_XY_reverse(uint32_t *key, uint32_t *key_xy)
{
uint32_t tmpkey[4];
toncset(key_xy, 0, 16);
toncset(tmpkey, 0, 16);
tonccpy(tmpkey, key, 16);
key_xy[0] = 0x1a4f3e79;
key_xy[1] = 0x2a680f5f;
key_xy[2] = 0x29590258;
key_xy[3] = 0xfffefb4e;
n128_rrot((uint64_t*)tmpkey, 42);
n128_sub((uint64_t*)tmpkey, (uint64_t*)key_xy);
tonccpy(key_xy, tmpkey, 16);
}

View File

@ -1,16 +0,0 @@
#ifndef _H_F_XY
#define _H_F_XY
#ifdef __cplusplus
extern "C" {
#endif
void F_XY(uint32_t *key, uint32_t *key_x, uint32_t *key_y);
void F_XY_reverse(uint32_t *key, uint32_t *key_xy);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -15,25 +15,25 @@
#define copyBufSize 0x8000
#define shaChunkSize 0x10000
u8* copyBuf = (u8*)0x02004000;
// u8* copyBuf = (u8*)0x02004000;
ALIGN(4) u8* copyBuf[copyBufSize];
std::vector<ClipboardFile> clipboard;
std::vector<DirEntry> dirContents;
std::vector<DirEntry> subdirContents;
bool clipboardOn = false;
bool clipboardUsed = true;
static float getGbNumber(u64 bytes) {
float gbNumber = 0.0f;
for (u64 i = 0; i <= bytes; i += 0x6666666) {
gbNumber += 0.1f;
}
for (u64 i = 0; i <= bytes; i += 0x6666666) { gbNumber += 0.1f; }
return gbNumber;
}
static float getTbNumber(u64 bytes) {
float tbNumber = 0.0f;
for (u64 i = 0; i <= bytes; i += 0x1999999999) {
tbNumber += 0.01f;
}
for (u64 i = 0; i <= bytes; i += 0x1999999999) { tbNumber += 0.01f; }
return tbNumber;
}
@ -176,9 +176,8 @@ int trimNds(const char *fileName) {
}
void dirCopy(const DirEntry &entry, int i, const char *destinationPath, const char *sourcePath) {
std::vector<DirEntry> dirContents;
dirContents.clear();
if (entry.isDirectory) chdir((sourcePath + ("/" + entry.name)).c_str());
if (entry.isDirectory)chdir((sourcePath + ("/" + entry.name)).c_str());
getDirectoryContents(dirContents);
if (((int)dirContents.size()) == 1) mkdir((destinationPath + ("/" + entry.name)).c_str(), 0777);
if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry.name)).c_str(), (destinationPath + ("/" + entry.name)).c_str());
@ -192,7 +191,6 @@ u64 dirSize(const std::vector<DirEntry> &dirContents) {
continue;
if(entry.isDirectory) {
std::vector<DirEntry> subdirContents;
if(chdir(entry.name.c_str()) == 0 && getDirectoryContents(subdirContents)) {
size += dirSize(subdirContents);
chdir("..");

View File

@ -39,7 +39,6 @@
#include "fileOperations.h"
#include "driveMenu.h"
#include "driveOperations.h"
#include "dumpOperations.h"
#include "font.h"
#include "hexEditor.h"
#include "my_sd.h"
@ -179,9 +178,7 @@ FileOperation fileBrowse_A(DirEntry* entry, const char *curdir) {
int y = font->calcHeight(fullPath) + 1;
if (!entry->isDirectory) {
if (entry->isApp) {
operations.push_back(FileOperation::bootFile);
}
if (entry->isApp)operations.push_back(FileOperation::bootFile);
if(extension(entry->name, {"nds", "dsi", "ids", "app", "srl"})) {
if(currentDrive != Drive::nitroFS)
@ -189,13 +186,6 @@ FileOperation fileBrowse_A(DirEntry* entry, const char *curdir) {
operations.push_back(FileOperation::ndsInfo);
operations.push_back(FileOperation::trimNds);
}
if(extension(entry->name, {"sav", "sav1", "sav2", "sav3", "sav4", "sav5", "sav6", "sav7", "sav8", "sav9"})) {
if(!(io_dldi_data->ioInterface.features & FEATURE_SLOT_NDS) || entry->size <= (1 << 20))
operations.push_back(FileOperation::restoreSaveNds);
if(isRegularDS && (entry->size == 512 || entry->size == 8192 || entry->size == 32768 || entry->size == 65536 || entry->size == 131072
|| entry->size == 528 || entry->size == 8208 || entry->size == 32784 || entry->size == 65552 || entry->size == 131088))
operations.push_back(FileOperation::restoreSaveGba);
}
if(currentDrive != Drive::fatImg && extension(entry->name, {"img", "sd", "sav", "pub", "pu1", "pu2", "pu3", "pu4", "pu5", "pu6", "pu7", "pu8", "pu9", "prv", "pr1", "pr2", "pr3", "pr4", "pr5", "pr6", "pr7", "pr8", "pr9", "0000"})) {
operations.push_back(FileOperation::mountImg);
}
@ -207,20 +197,14 @@ FileOperation fileBrowse_A(DirEntry* entry, const char *curdir) {
// The bios SHA1 functions are only available on the DSi
// https://problemkaputt.de/gbatek.htm#biossha1functionsdsionly
if (bios9iEnabled) {
operations.push_back(FileOperation::calculateSHA1);
}
if (bios9iEnabled)operations.push_back(FileOperation::calculateSHA1);
}
operations.push_back(FileOperation::showInfo);
if (sdMounted && (strcmp(curdir, "sd:/gm9i/out/") != 0)) {
operations.push_back(FileOperation::copySdOut);
}
if (sdMounted && (strcmp(curdir, "sd:/gm9i/out/") != 0))operations.push_back(FileOperation::copySdOut);
if (flashcardMounted && (strcmp(curdir, "fat:/gm9i/out/") != 0)) {
operations.push_back(FileOperation::copyFatOut);
}
if (flashcardMounted && (strcmp(curdir, "fat:/gm9i/out/") != 0))operations.push_back(FileOperation::copyFatOut);
while (true) {
font->clear(false);
@ -243,15 +227,6 @@ FileOperation fileBrowse_A(DirEntry* entry, const char *curdir) {
case FileOperation::trimNds:
font->print(optionsCol, row++, false, STR_TRIM_NDS, alignStart);
break;
case FileOperation::restoreSaveNds:
if(!isRegularDS)
font->print(optionsCol, row++, false, STR_RESTORE_SAVE, alignStart);
else
font->print(optionsCol, row++, false, STR_RESTORE_SAVE_NDS, alignStart);
break;
case FileOperation::restoreSaveGba:
font->print(optionsCol, row++, false, STR_RESTORE_SAVE_GBA, alignStart);
break;
case FileOperation::mountImg:
font->print(optionsCol, row++, false, STR_MOUNT_FAT_IMG, alignStart);
break;
@ -317,12 +292,6 @@ FileOperation fileBrowse_A(DirEntry* entry, const char *curdir) {
font->print(optionsCol, optionOffset + y, false, STR_LOADING, alignStart);
font->update(false);
break;
} case FileOperation::restoreSaveNds: {
ndsCardSaveRestore(entry->name.c_str());
break;
} case FileOperation::restoreSaveGba: {
gbaCartSaveRestore(entry->name.c_str());
break;
} case FileOperation::copySdOut: {
if (access("sd:/gm9i", F_OK) != 0) {
font->print(optionsCol, optionOffset + y, false, STR_CREATING_DIRECTORY, alignStart);

View File

@ -43,8 +43,6 @@ enum class FileOperation {
ndsInfo,
trimNds,
mountImg,
restoreSaveNds,
restoreSaveGba,
showInfo,
copySdOut,
copyFatOut,
@ -61,3 +59,4 @@ bool getDirectoryContents (std::vector<DirEntry>& dirContents);
#endif //FILE_BROWSE_H

View File

@ -1,362 +0,0 @@
/*
exptools.cpp
Copyright (C) 2007-2009 somebody
Copyright (C) 2009 yellow wood goblin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "exptools.h"
#define _PSRAM 0x08060000 // an offset into PSRAM to write to so stuff doesn't get lost...
void cExpansion::OpenNorWrite(void)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9c40000=0x1500;
*(vu16*)0x9fc0000=0x1500;
}
void cExpansion::CloseNorWrite(void)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9c40000=0xd200;
*(vu16*)0x9fc0000=0x1500;
}
void cExpansion::SetRompage(u16 page)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9880000=page;
*(vu16*)0x9fc0000=0x1500;
}
void cExpansion::SetRampage(u16 page)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9c00000=page;
*(vu16*)0x9fc0000=0x1500;
iRamPage=page;
}
u16 cExpansion::Rampage(void)
{
return iRamPage;
}
void cExpansion::SetSerialMode(void)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9a40000=0xe200;
*(vu16*)0x9fc0000=0x1500;
}
void cExpansion::SetShake(u16 data)
{
*(vu16*)0x9fe0000=0xd200;
*(vu16*)0x8000000=0x1500;
*(vu16*)0x8020000=0xd200;
*(vu16*)0x8040000=0x1500;
*(vu16*)0x9e20000=data;
*(vu16*)0x9fc0000=0x1500;
}
void cExpansion::EnableBrowser(void)
{
for(u32 i=0;i<0x100;i+=4)
{
*(vu32*)(0x9000000+i)=0xffffffff;
*(vu32*)(0x8000000+i)=0xffffffff;
}
*(vu32*)0x90000b0=0xffff;
*(vu32*)0x90000b4=0x24242400;
*(vu32*)0x90000b8=0xffffffff;
*(vu32*)0x90000bc=0x7fffffff;
*(vu32*)0x901fffc=0x7fffffff;
*(vu16*)0x9240002=1;
}
void cExpansion::Block_Erase(u32 blockAdd)
{
vu16 v1,v2;
u32 Address;
u32 loop;
u32 off=0;
if((blockAdd>=0x1000000)&&(iId==0x227E2202))
{
off=0x1000000;
*((vu16*)(FlashBase+off+0x555*2))=0xF0;
*((vu16*)(FlashBase+off+0x1555*2))=0xF0;
}
else
off=0;
Address=blockAdd;
*((vu16*)(FlashBase+0x555*2))=0xF0;
*((vu16*)(FlashBase+0x1555*2))=0xF0;
if((blockAdd==0)||(blockAdd==0x1FC0000)||(blockAdd==0xFC0000)||(blockAdd==0x1000000))
{
for(loop=0;loop<0x40000;loop+=0x8000)
{
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+off+0x555*2))=0x80;
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+Address+loop))=0x30;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+off+0x1555*2))=0x80;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+Address+loop+0x2000))=0x30;
*((vu16*)(FlashBase+off+0x2555*2))=0xAA;
*((vu16*)(FlashBase+off+0x22AA*2))=0x55;
*((vu16*)(FlashBase+off+0x2555*2))=0x80;
*((vu16*)(FlashBase+off+0x2555*2))=0xAA;
*((vu16*)(FlashBase+off+0x22AA*2))=0x55;
*((vu16*)(FlashBase+Address+loop+0x4000))=0x30;
*((vu16*)(FlashBase+off+0x3555*2))=0xAA;
*((vu16*)(FlashBase+off+0x32AA*2))=0x55;
*((vu16*)(FlashBase+off+0x3555*2))=0x80;
*((vu16*)(FlashBase+off+0x3555*2))=0xAA;
*((vu16*)(FlashBase+off+0x32AA*2))=0x55;
*((vu16*)(FlashBase+Address+loop+0x6000))=0x30;
do
{
v1=*((vu16*)(FlashBase+Address+loop));
v2=*((vu16*)(FlashBase+Address+loop));
} while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+Address+loop+0x2000));
v2=*((vu16*)(FlashBase+Address+loop+0x2000));
} while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+Address+loop+0x4000));
v2=*((vu16*)(FlashBase+Address+loop+0x4000));
}while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+Address+loop+0x6000));
v2=*((vu16*)(FlashBase+Address+loop+0x6000));
}while(v1!=v2);
}
}
else
{
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+off+0x555*2))=0x80;
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+Address))=0x30;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+off+0x1555*2))=0x80;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+Address+0x2000))=0x30;
do
{
v1=*((vu16*)(FlashBase+Address));
v2=*((vu16*)(FlashBase+Address));
}while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+Address+0x2000));
v2=*((vu16*)(FlashBase+Address+0x2000));
}while(v1!=v2);
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+off+0x555*2))=0x80;
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+Address+0x20000))=0x30;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+off+0x1555*2))=0x80;
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+Address+0x2000+0x20000))=0x30;
do
{
v1=*((vu16*)(FlashBase+Address+0x20000));
v2=*((vu16*)(FlashBase+Address+0x20000));
} while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+Address+0x2000+0x20000));
v2=*((vu16*)(FlashBase+Address+0x2000+0x20000));
} while(v1!=v2);
}
}
void cExpansion::WriteNorFlash(u32 address,const u8* buffer,u32 size)
{
vu16 v1,v2;
/*register*/ u32 loopwrite;
vu16* buf=(vu16*)buffer;
u32 size2,lop;
u32 mapaddress;
u32 j;
v1=0;v2=1;
u32 off=0;
if((address>=0x1000000)&&(iId==0x227E2202))
{
off=0x1000000;
}
else
off=0;
if(size>0x4000)
{
size2=size>>1;
lop=2;
}
else
{
size2=size;
lop=1;
}
mapaddress=address;
for(j=0;j<lop;j++)
{
if(j!=0)
{
mapaddress+=0x4000;
buf=(vu16*)(buffer+0x4000);
}
for(loopwrite=0;loopwrite<(size2>>2);loopwrite++)
{
*((vu16*)(FlashBase+off+0x555*2))=0xAA;
*((vu16*)(FlashBase+off+0x2AA*2))=0x55;
*((vu16*)(FlashBase+off+0x555*2))=0xA0;
*((vu16*)(FlashBase+mapaddress+loopwrite*2))=buf[loopwrite];
*((vu16*)(FlashBase+off+0x1555*2))=0xAA;
*((vu16*)(FlashBase+off+0x12AA*2))=0x55;
*((vu16*)(FlashBase+off+0x1555*2))=0xA0;
*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2))=buf[0x1000+loopwrite];
do
{
v1=*((vu16*)(FlashBase+mapaddress+loopwrite*2));
v2=*((vu16*)(FlashBase+mapaddress+loopwrite*2));
}while(v1!=v2);
do
{
v1=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2));
v2=*((vu16*)(FlashBase+mapaddress+0x2000+loopwrite*2));
}while(v1!=v2);
}
}
}
void cExpansion::WritePSRAM(u32 address,const u8* buffer,u32 size)
{
u16* addr=(u16*)(address+_PSRAM);
u16* pData=(u16*)buffer;
for(u32 i=0;i<size;i+=2)
{
addr[i>>1]=pData[i>>1];
}
}
void cExpansion::WriteSram(uint32 address,const u8* data,uint32 size)
{
for(u32 i=0;i<size;i++)
*(u8*)(address+i)=data[i];
}
void cExpansion::ReadSram(uint32 address,u8* data,uint32 size)
{
u16* pData=(u16*)data;
for(u32 i=0;i<size;i+=2)
{
pData[i>>1]=*(u8*)(address+i)+(*(u8*)(address+i+1)*0x100);
}
}
void cExpansion::SoftReset(void)
{
CloseNorWrite();
SetRompage(0);
SetRampage(16);
SetShake(8);
}
void cExpansion::ReadNorFlashID(void)
{
vu16 id1,id2;
*((vu16*)(FlashBase+0x555*2))=0xAA;
*((vu16*)(FlashBase+0x2AA*2))=0x55;
*((vu16*)(FlashBase+0x555*2))=0x90;
*((vu16*)(FlashBase+0x1555*2))=0xAA;
*((vu16*)(FlashBase+0x12AA*2))=0x55;
*((vu16*)(FlashBase+0x1555*2))=0x90;
id1=*((vu16*)(FlashBase+0x2));
id2=*((vu16*)(FlashBase+0x2002));
if((id1!=0x227E)||(id2!=0x227E)) return;
id1=*((vu16*)(FlashBase+0xE*2));
id2=*((vu16*)(FlashBase+0x100e*2));
if(id1==0x2218&&id2==0x2218) //H6H6
{
iId=0x227E2218;
return;
}
if((id1==0x2202&&id2==0x2202)
||(id1==0x2202&&id2==0x2220)
||(id1==0x2202&&id2==0x2215)) //VZ064
{
iId=0x227E2202;
return;
}
}
void cExpansion::ChipReset(void)
{
*((vu16*)(FlashBase))=0xF0;
*((vu16*)(FlashBase+0x1000*2))=0xF0;
if(iId==0x227E2202)
{
*((vu16*)(FlashBase+0x1000000))=0xF0 ;
*((vu16*)(FlashBase+0x1000000+0x1000*2))=0xF0;
}
}

View File

@ -1,69 +0,0 @@
/*
exptools.h
Copyright (C) 2007-2009 somebody
Copyright (C) 2009 yellow wood goblin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __EXPTOOLS_H__
#define __EXPTOOLS_H__
#include <nds.h>
#include "singleton.h"
class cExpansion
{
public:
enum TPages
{
ENorPage=16,
EPsramPage=96
};
public:
static void OpenNorWrite(void);
static void CloseNorWrite(void);
static void SetRompage(u16 page);
void SetRampage(u16 page);
u16 Rampage(void);
static void SetSerialMode(void);
static void SetShake(u16 data);
static void EnableBrowser(void);
static void WritePSRAM(u32 address,const u8* buffer,u32 size);
static void WriteSram(uint32 address,const u8* data,uint32 size);
static void ReadSram(uint32 address,u8* data,uint32 size);
public:
void SoftReset(void);
public:
cExpansion(): iId(0),iRamPage(ENorPage) {SetShake(8);OpenNorWrite();ReadNorFlashID();ChipReset();CloseNorWrite();};
void Block_Erase(u32 blockAdd);
void WriteNorFlash(u32 address,const u8* buffer,u32 size);
bool IsValid(void) {return iId;};
private:
void ReadNorFlashID(void);
void ChipReset(void);
private:
enum
{
FlashBase=0x08000000
};
private:
u32 iId;
u16 iRamPage;
};
typedef singleton<cExpansion> cExpansion_s;
inline cExpansion& expansion() {return cExpansion_s::instance();}
#endif

View File

@ -1,114 +0,0 @@
/*
iointerface.c for G6 flash card
Written by Viruseb (viruseb@hotmail.com)
Many thanks to Puyo for his help in the reading code and ecc generation
and Theli for remote debbuging.
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
If you wish to understand how the code works, I encourage you reading
the datasheet of K9K4G08U0M nand flash device from Samsung before.
Just some figures to keep in mind :
1 page = 4 sectors + 64byte
1 block = 64 pages = 256 sectors
1 4G device = 4096 blocks
The spare 64byte in page are use :
- to store the ECC. There is 3bytes ecc per 256bytes (bytes 8...15+numsector*16).
- to store lookuptable values (bytes 4..7).
04/12/06 : Version 0.10
Just freshly written. Not tested on real G6L thought.
Extreme caution have to be taken when testing WriteBlockFunction
since it may brick your G6L or more likely corrupt your data
and formating can be necessary.
05/12/06 : Version 0.11
Thank to Theli, a lot of stupid mistakes removed, a lot of debugging done.
Reading code checked against Puyo's code.
Device and FAT table is recognised by Fat_InitFiles()
Known issues : DMA read (G6_ReadDMA) is malfunctionning
Strange things append when trying to read more than 1 sectors at a time
Have to check LookUpTable values against Puyo's LookUpTable they seems differents after 512values
19/12/06 : Version 0.12
Reading code ok
20/12/06 : Version 0.13
Some reading bugs corrected
07/01/07 : Version 0.14
Writing code finaly working. Need some optimizations.
10/01/07 : Version 0.15
Code cleaning. Need to add DMA R/W and use of cache programming in later version.
03/02/07 : Version 0.16
Unaligned R/W supported.
Write code rewritten, using cache programming now.
04/03/07 : Version 0.17
VerifyBlockFunc corrected (no more in use now)
23/03/07 : Version 0.18
a bug corrected in make_ecc_256
25/03/07 : Version 0.19
Improved writing speed
*/
#include "io_g6_common.h"
static u16 _G6_readHalfword (u32 addr) {
return *((vu16*)addr);
}
/*-----------------------------------------------------------------
SelectOperation
??
u16 op IN : Operation to select
-----------------------------------------------------------------*/
void _G6_SelectOperation(u16 op)
{
_G6_readHalfword (0x09000000);
_G6_readHalfword (0x09FFFFE0);
_G6_readHalfword (0x09FFFFEC);
_G6_readHalfword (0x09FFFFEC);
_G6_readHalfword (0x09FFFFEC);
_G6_readHalfword (0x09FFFFFC);
_G6_readHalfword (0x09FFFFFC);
_G6_readHalfword (0x09FFFFFC);
_G6_readHalfword (0x09FFFF4A);
_G6_readHalfword (0x09FFFF4A);
_G6_readHalfword (0x09FFFF4A);
_G6_readHalfword (0x09200000 + (op<<1));
_G6_readHalfword (0x09FFFFF0);
_G6_readHalfword (0x09FFFFE8);
}

View File

@ -1,103 +0,0 @@
/*
iointerface.c for G6 flash card
Written by Viruseb (viruseb@hotmail.com)
Many thanks to Puyo for his help in the reading code and ecc generation
and Theli for remote debbuging.
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
If you wish to understand how the code works, I encourage you reading
the datasheet of K9K4G08U0M nand flash device from Samsung before.
Just some figures to keep in mind :
1 page = 4 sectors + 64byte
1 block = 64 pages = 256 sectors
1 4G device = 4096 blocks
The spare 64byte in page are use :
- to store the ECC. There is 3bytes ecc per 256bytes (bytes 8...15+numsector*16).
- to store lookuptable values (bytes 4..7).
04/12/06 : Version 0.10
Just freshly written. Not tested on real G6L thought.
Extreme caution have to be taken when testing WriteBlockFunction
since it may brick your G6L or more likely corrupt your data
and formating can be necessary.
05/12/06 : Version 0.11
Thank to Theli, a lot of stupid mistakes removed, a lot of debugging done.
Reading code checked against Puyo's code.
Device and FAT table is recognised by Fat_InitFiles()
Known issues : DMA read (G6_ReadDMA) is malfunctionning
Strange things append when trying to read more than 1 sectors at a time
Have to check LookUpTable values against Puyo's LookUpTable they seems differents after 512values
19/12/06 : Version 0.12
Reading code ok
20/12/06 : Version 0.13
Some reading bugs corrected
07/01/07 : Version 0.14
Writing code finaly working. Need some optimizations.
10/01/07 : Version 0.15
Code cleaning. Need to add DMA R/W and use of cache programming in later version.
03/02/07 : Version 0.16
Unaligned R/W supported.
Write code rewritten, using cache programming now.
04/03/07 : Version 0.17
VerifyBlockFunc corrected (no more in use now)
23/03/07 : Version 0.18
a bug corrected in make_ecc_256
25/03/07 : Version 0.19
Improved writing speed
*/
#ifndef IO_G6_COMMON_H
#define IO_G6_COMMON_H
#include <nds/ndstypes.h>
#ifdef __cplusplus
extern "C" {
#endif
// Values for changing mode
#define G6_MODE_RAM 6
#define G6_MODE_MEDIA 3
extern void _G6_SelectOperation(u16 op);
#ifdef __cplusplus
}
#endif
#endif // IO_G6_COMMON_H

View File

@ -1,60 +0,0 @@
/*
io_m3_common.c
Routines common to all version of the M3
Some code based on M3 SD drivers supplied by M3Adapter.
Some code written by SaTa may have been unknowingly used.
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "io_m3_common.h"
static u16 _M3_readHalfword (u32 addr) {
return *((vu16*)addr);
}
void _M3_changeMode (u32 mode) {
_M3_readHalfword (0x08e00002);
_M3_readHalfword (0x0800000e);
_M3_readHalfword (0x08801ffc);
_M3_readHalfword (0x0800104a);
_M3_readHalfword (0x08800612);
_M3_readHalfword (0x08000000);
_M3_readHalfword (0x08801b66);
_M3_readHalfword (0x08000000 + (mode << 1));
_M3_readHalfword (0x0800080e);
_M3_readHalfword (0x08000000);
if ((mode & 0x0f) != 4) {
_M3_readHalfword (0x09000000);
} else {
_M3_readHalfword (0x080001e4);
_M3_readHalfword (0x080001e4);
_M3_readHalfword (0x08000188);
_M3_readHalfword (0x08000188);
}
}

View File

@ -1,57 +0,0 @@
/*
io_m3_common.h
Routines common to all version of the M3
Some code based on M3 SD drivers supplied by M3Adapter.
Some code written by SaTa may have been unknowingly used.
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2006-07-11 - Chishm
* Original release
*/
#ifndef IO_M3_COMMON_H
#define IO_M3_COMMON_H
#include <nds/ndstypes.h>
#ifdef __cplusplus
extern "C" {
#endif
// Values for changing mode
#define M3_MODE_RAM 0x00400006
#define M3_MODE_ROM 0x00400004
#define M3_MODE_MEDIA 0x00400003
extern void _M3_changeMode (u32 mode);
#ifdef __cplusplus
}
#endif
#endif // IO_M3_COMMON_H

View File

@ -1,47 +0,0 @@
/*
io_m3_common.h
Routines common to all version of the Super Card
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "io_sc_common.h"
/*-----------------------------------------------------------------
_SC_changeMode (was SC_Unlock)
Added by MightyMax
Modified by Chishm
Modified again by loopy
1=ram(readonly), 5=ram, 3=SD interface?
-----------------------------------------------------------------*/
void _SC_changeMode(u8 mode) {
vu16 *unlockAddress = (vu16*)0x09FFFFFE;
*unlockAddress = 0xA55A ;
*unlockAddress = 0xA55A ;
*unlockAddress = mode ;
*unlockAddress = mode ;
}

View File

@ -1,53 +0,0 @@
/*
io_sc_common.h
Routines common to all version of the Super Card
Copyright (c) 2006 Michael "Chishm" Chisholm
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2006-07-11 - Chishm
* Original release
*/
#ifndef IO_SC_COMMON_H
#define IO_SC_COMMON_H
#include <nds/ndstypes.h>
#ifdef __cplusplus
extern "C" {
#endif
// Values for changing mode
#define SC_MODE_RAM 0x5
#define SC_MODE_MEDIA 0x3
#define SC_MODE_RAM_RO 0x1
extern void _SC_changeMode (u8 mode);
#ifdef __cplusplus
}
#endif
#endif // IO_SC_COMMON_H

View File

@ -1,491 +0,0 @@
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
*
* gba.cpp: Functions for working with the GBA-slot on a Nintendo DS.
* EZFlash 3-in-1 functions are found in dsCard.h/.cpp
*
* Copyright (C) Pokedoc (2010)
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <nds.h>
#include <fat.h>
#include <sys/iosupport.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/unistd.h>
#include <algorithm>
#include <nds/dma.h>
#include <dirent.h>
#include "gba.h"
inline u32 min(u32 i, u32 j) { return (i < j) ? i : j;}
inline u32 max(u32 i, u32 j) { return (i > j) ? i : j;}
// -----------------------------------------------------
#define MAGIC_EEPR 0x52504545
#define MAGIC_SRAM 0x4d415253
#define MAGIC_FLAS 0x53414c46
#define MAGIC_H1M_ 0x5f4d3148
// -----------------------------------------------------------
bool gbaIsGame()
{
// look for some magic bytes of the compressed Nintendo logo
uint32 *data = (uint32*)0x08000004;
if (*data == 0x51aeff24) {
data ++; data ++;
if (*data == 0x0a82843d)
return true;
}
return false;
}
void readEeprom(u8 *dst, u32 src, u32 len) {
// EEPROM reading needs to happen on ARM7
sysSetCartOwner(BUS_OWNER_ARM7);
fifoSendValue32(FIFO_USER_01, 0x44414552 /* 'READ' */);
fifoSendAddress(FIFO_USER_01, dst);
fifoSendValue32(FIFO_USER_01, src);
fifoSendValue32(FIFO_USER_01, len);
// Read the data from FIFO
u8 *ptr = dst;
while(ptr < dst + len) {
if(fifoCheckDatamsg(FIFO_USER_02)) {
fifoGetDatamsg(FIFO_USER_02, 8, ptr);
ptr += 8;
}
}
sysSetCartOwner(BUS_OWNER_ARM9);
}
void writeEeprom(u32 dst, u8 *src, u32 len) {
// EEPROM writing needs to happen on ARM7
sysSetCartOwner(BUS_OWNER_ARM7);
fifoSendValue32(FIFO_USER_01, 0x54495257 /* 'WRIT' */);
fifoSendValue32(FIFO_USER_01, dst);
fifoSendAddress(FIFO_USER_01, src);
fifoSendValue32(FIFO_USER_01, len);
// Wait for it to finish
fifoWaitValue32(FIFO_USER_02);
fifoGetValue32(FIFO_USER_02);
sysSetCartOwner(BUS_OWNER_ARM9);
}
saveTypeGBA gbaGetSaveType() {
// Search for any one of the magic version strings in the ROM. They are always dword-aligned.
uint32 *data = (uint32*)0x08000000;
for (int i = 0; i < (0x02000000 >> 2); i++, data++) {
if (*data == MAGIC_EEPR) {
u8 *buffer = new u8[0x2000];
readEeprom(buffer, 0, 0x2000);
// Check if first 0x800 bytes are duplicates of the first 8
for(int j = 8; j < 0x800; j += 8) {
if(memcmp(buffer, buffer + j, 8) != 0) {
delete[] buffer;
return SAVE_GBA_EEPROM_8;
}
}
delete[] buffer;
return SAVE_GBA_EEPROM_05;
} else if (*data == MAGIC_SRAM) {
// *always* 32 kB
return SAVE_GBA_SRAM_32;
} else if (*data == MAGIC_FLAS) {
// 64 kB oder 128 kB
uint32 *data2 = data + 1;
if (*data2 == MAGIC_H1M_)
return SAVE_GBA_FLASH_128;
else
return SAVE_GBA_FLASH_64;
}
}
return SAVE_GBA_NONE;
}
uint32 gbaGetSaveSizeLog2(saveTypeGBA type)
{
if (type == SAVE_GBA_NONE)
type = gbaGetSaveType();
switch (type) {
case SAVE_GBA_EEPROM_05:
return 9;
case SAVE_GBA_EEPROM_8:
return 13;
case SAVE_GBA_SRAM_32:
return 15;
case SAVE_GBA_FLASH_64:
return 16;
case SAVE_GBA_FLASH_128:
return 17;
case SAVE_GBA_NONE:
default:
return 0;
}
}
uint32 gbaGetSaveSize(saveTypeGBA type)
{
if (type == SAVE_GBA_NONE)
return 0;
else
return 1 << gbaGetSaveSizeLog2(type);
}
bool gbaReadSave(u8 *dst, u32 src, u32 len, saveTypeGBA type)
{
int nbanks = 2; // for type 4,5
switch (type) {
case SAVE_GBA_EEPROM_05:
case SAVE_GBA_EEPROM_8: {
readEeprom(dst, src, len);
break;
}
case SAVE_GBA_SRAM_32: {
// SRAM: blind copy
int start = 0x0a000000 + src;
u8 *tmpsrc = (u8*)start;
sysSetBusOwners(true, true);
for (u32 i = 0; i < len; i++, tmpsrc++, dst++)
*dst = *tmpsrc;
break;
}
case SAVE_GBA_FLASH_64:
// FLASH - must be opend by register magic, then blind copy
nbanks = 1;
case SAVE_GBA_FLASH_128:
for (int j = 0; j < nbanks; j++) {
// we need to wait a few cycles before the hardware reacts!
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0xb0;
swiDelay(10);
*(vu8*)0x0a000000 = (u8)j;
swiDelay(10);
u32 start, sublen;
if (j == 0) {
start = 0x0a000000 + src;
sublen = (src < 0x10000) ? min(len, (1 << 16) - src) : 0;
} else if (j == 1) {
start = max(0x09ff0000 + src, 0x0a000000);
sublen = (src + len < 0x10000) ? 0 : min(len, len - (0x10000 - src));
}
u8 *tmpsrc = (u8*)start;
sysSetBusOwners(true, true);
for (u32 i = 0; i < sublen; i++, tmpsrc++, dst++)
*dst = *tmpsrc;
}
break;
case SAVE_GBA_NONE:
break;
}
return true;
}
u16 gbaGetFlashId()
{
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0x90; // ID mode
swiDelay(10);
//
u8 dev = *(u8*)0x0a000001;
u8 man = *(u8*)0x0a000000;
//
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0xf0; // leave ID mode
swiDelay(10);
//
//char txt[128];
// sprintf(txt, "Man: %x, Dev: %x", man, dev);
// displayStateF(STR_STR, txt);
return dev << 8 | man;
}
bool gbaIsAtmel()
{
return gbaGetFlashId() == 0x3d1f;
}
bool gbaWriteSave(u32 dst, u8 *src, u32 len, saveTypeGBA type)
{
int nbanks = 2; // for type 4,5
switch (type) {
case SAVE_GBA_EEPROM_05:
case SAVE_GBA_EEPROM_8: {
writeEeprom(dst, src, len);
break;
}
case SAVE_GBA_SRAM_32: {
// SRAM: blind write
u32 start = 0x0a000000 + dst;
u8 *tmpdst = (u8*)start;
sysSetBusOwners(true, true);
for (u32 i = 0; i < len; i++, tmpdst++, src++) {
*tmpdst = *src;
swiDelay(10); // mabe we don't need this, but better safe than sorry
}
break;
}
case SAVE_GBA_FLASH_64: {
bool atmel = gbaIsAtmel();
if (atmel) {
// only 64k, no bank switching required
u32 len7 = len >> 7;
u8 *tmpdst = (u8*)(0x0a000000+dst);
for (u32 j = 0; j < len7; j++) {
u32 ime = enterCriticalSection();
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0xa0;
swiDelay(10);
for (int i = 0; i < 128; i++) {
*tmpdst = *src;
swiDelay(10);
}
leaveCriticalSection(ime);
while (*tmpdst != *src) {swiDelay(10);}
}
break;
}
nbanks = 1;
}
case SAVE_GBA_FLASH_128:
// FLASH - must be opend by register magic, erased and then rewritten
// FIXME: currently, you can only write "all or nothing"
for (int j = 0; j < nbanks; j++) {
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0xb0;
swiDelay(10);
*(vu8*)0x0a000000 = (u8)j;
swiDelay(10);
//
u32 start, sublen;
if (j == 0) {
start = 0x0a000000 + dst;
sublen = (dst < 0x10000) ? min(len, (1 << 16) - dst) : 0;
} else if (j == 1) {
start = max(0x09ff0000 + dst, 0x0a000000);
sublen = (dst + len < 0x10000) ? 0 : min(len, len - (0x10000 - dst));
}
u8 *tmpdst = (u8*)start;
sysSetBusOwners(true, true);
for (u32 i = 0; i < sublen; i++, tmpdst++, src++) {
// we need to wait a few cycles before the hardware reacts!
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0xa0; // write byte command
swiDelay(10);
//
*tmpdst = *src;
swiDelay(10);
//
while (*tmpdst != *src) {swiDelay(10);}
}
}
break;
case SAVE_GBA_NONE:
break;
}
return true;
}
bool gbaFormatSave(saveTypeGBA type)
{
switch (type) {
case SAVE_GBA_EEPROM_05:
case SAVE_GBA_EEPROM_8:
// EEPROM doesn't need erasing
break;
case SAVE_GBA_SRAM_32:
{
// memset(data, 0, 1 << 15);
u8 *data = new u8[1 << 15]();
gbaWriteSave(0, data, 1 << 15, SAVE_GBA_SRAM_32);
delete[] data;
}
break;
case SAVE_GBA_FLASH_64:
case SAVE_GBA_FLASH_128:
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0x80; // erase command
swiDelay(10);
*(vu8*)0x0a005555 = 0xaa;
swiDelay(10);
*(vu8*)0x0a002aaa = 0x55;
swiDelay(10);
*(vu8*)0x0a005555 = 0x10; // erase entire chip
swiDelay(10);
while (*(u8*)0x0a000000 != 0xff)
swiDelay(10);
break;
case SAVE_GBA_NONE:
break;
}
return true;
}
#define GPIO_DAT (*(vu16*) 0x080000c4)
#define GPIO_DIR (*(vu16*) 0x080000c6)
#define GPIO_CNT (*(vu16*) 0x080000c8)
#define RTC_CMD_READ(x) (((x)<<1) | 0x61)
#define RTC_CMD_WRITE(x) (((x)<<1) | 0x60)
static void rtcEnable()
{
GPIO_CNT = 1;
}
static void rtcDisable()
{
GPIO_CNT = 0;
}
static void rtcWriteCmd(u8 cmd)
{
int l;
u16 b;
u16 v = cmd <<1;
for(l=7; l>=0; l--)
{
b = (v>>l) & 0x2;
GPIO_DAT = b | 4;
GPIO_DAT = b | 4;
GPIO_DAT = b | 4;
GPIO_DAT = b | 5;
}
}
static void rtcWriteData(u8 data)
{
int l;
u16 b;
u16 v = data <<1;
for(l=0; l<8; l++)
{
b = (v>>l) & 0x2;
GPIO_DAT = b | 4;
GPIO_DAT = b | 4;
GPIO_DAT = b | 4;
GPIO_DAT = b | 5;
}
}
static u8 rtcReadData()
{
int j,l;
u16 b;
int v = 0;
for(l=0; l<8; l++)
{
for(j=0;j<5; j++)
GPIO_DAT = 4;
GPIO_DAT = 5;
b = GPIO_DAT;
v = v | ((b & 2)<<l);
}
v = v>>1;
return v;
}
bool gbaGetRtc(u8 *rtc)
{
rtcEnable();
int i;
GPIO_DAT = 1;
GPIO_DIR = 7;
GPIO_DAT = 1;
GPIO_DAT = 5;
rtcWriteCmd(RTC_CMD_READ(2));
GPIO_DIR = 5;
for(i=0; i<4; i++)
rtc[i] = rtcReadData();
GPIO_DIR = 5;
for(i=4; i<7; i++)
rtc[i] = rtcReadData();
GPIO_DAT = 1;
GPIO_DIR = 7;
GPIO_DAT = 1;
GPIO_DAT = 5;
rtcWriteCmd(RTC_CMD_READ(4));
GPIO_DIR = 5;
rtc[7] = rtcReadData();
rtcDisable();
// Month must be 1 to 12 in BCD for valid RTC
// If month is 0, invalid RTC
return rtc[RTC_MONTH] >= 0x01 && rtc[RTC_MONTH] <= 0x12;
}
static uint8_t unBCD(uint8_t byte) {
return (byte >> 4) * 10 + (byte & 0xF);
}
struct tm gbaRtcToTm(const u8 *rtc)
{
struct tm res;
res.tm_year = unBCD(rtc[RTC_YEAR]) + 100;
res.tm_mon = unBCD(rtc[RTC_MONTH]) - 1;
res.tm_mday = unBCD(rtc[RTC_DAY]);
res.tm_hour = unBCD(rtc[RTC_HOUR]);
res.tm_min = unBCD(rtc[RTC_MINUTE]);
res.tm_sec = unBCD(rtc[RTC_SECOND]);
res.tm_isdst = -1;
return res;
}

View File

@ -1,63 +0,0 @@
/*
* savegame_manager: a tool to backup and restore savegames from Nintendo
* DS cartridges. Nintendo DS and all derivative names are trademarks
* by Nintendo.
*
* gba.h: header file for gba.cpp
*
* Copyright (C) Pokedoc (2010)
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __GBA_H__
#define __GBA_H__
enum saveTypeGBA {
SAVE_GBA_NONE = 0,
SAVE_GBA_EEPROM_05, // 512 bytes
SAVE_GBA_EEPROM_8, // 8k
SAVE_GBA_SRAM_32, // 32k
SAVE_GBA_FLASH_64, // 64k
SAVE_GBA_FLASH_128 // 128k
};
enum GbaRtc {
RTC_YEAR,
RTC_MONTH,
RTC_DAY,
RTC_WEEKDAY,
RTC_HOUR,
RTC_MINUTE,
RTC_SECOND,
RTC_CONTROL,
RTC_SIZE
};
// --------------------
bool gbaIsGame();
saveTypeGBA gbaGetSaveType();
uint32 gbaGetSaveSize(saveTypeGBA type = SAVE_GBA_NONE);
uint32 gbaGetSaveSizeLog2(saveTypeGBA type = SAVE_GBA_NONE);
u16 gbaGetFlashId();
bool gbaReadSave(u8 *dst, u32 src, u32 len, saveTypeGBA type);
bool gbaWriteSave(u32 dst, u8 *src, u32 len, saveTypeGBA type);
bool gbaFormatSave(saveTypeGBA type);
bool gbaGetRtc(u8 *rtc);
struct tm gbaRtcToTm(const u8 *rtc);
#endif // __GBA_H__

View File

@ -42,24 +42,15 @@ STRING(FILE_TOO_BIG, "%s is too large to copy to this drive. Please delete some
// Drive labels
STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)")
STRING(FLASHCARD_LABEL, "[fat:] FLASHCARD (%s)")
STRING(RAMDRIVE_LABEL, "[ram:] RAMDRIVE")
STRING(SYSNAND_LABEL, "[nand:] SYSNAND")
STRING(SYSNAND_PHOTO_LABEL, "[photo:] SYSNAND (photo)")
STRING(NITROFS_LABEL, "[nitro:] NDS GAME IMAGE")
STRING(FAT_LABEL, "[img:] FAT IMAGE (%s)")
STRING(GBA_GAMECART, "GBA GAMECART (%s)")
STRING(NDS_GAMECARD, "NDS GAMECARD (%s)")
STRING(NDS_GAMECARD_NO_TITLE, "NDS GAMECARD")
// Drive bottom screen labels
STRING(SD_FAT, "(SD FAT, %s)")
STRING(N_FREE, "%s free")
STRING(SLOT1_FAT, "(Slot-1 SD FAT, %s)")
STRING(GBA_GAME, "(GBA Game, %s)")
STRING(NDS_GAME, "(NDS Game, %s (%s trimmed))")
STRING(GAME_VIRTUAL, "(Game Virtual)")
STRING(RAMDRIVE_FAT, "(RAMdrive FAT, %s)")
STRING(SYSNAND_FAT, "(SysNAND FAT, %s)")
STRING(FAT_IMAGE, "(Image FAT, %s)")
// Bottom screen control info
@ -100,9 +91,6 @@ STRING(BOOT_FILE_DIRECT, "Boot file (Direct)")
STRING(MOUNT_NITROFS, "Mount NitroFS")
STRING(SHOW_NDS_INFO, "Show NDS file info")
STRING(TRIM_NDS, "Trim NDS file")
STRING(RESTORE_SAVE, "Restore save")
STRING(RESTORE_SAVE_NDS, "Restore save (Slot-1)")
STRING(RESTORE_SAVE_GBA, "Restore save (Slot-2)")
STRING(MOUNT_FAT_IMG, "Mount as FAT image")
STRING(OPEN_HEX, "Open in hex editor")
STRING(SHOW_DIRECTORY_INFO, "Show directory info")
@ -134,49 +122,8 @@ STRING(PRESS_B_TO_CANCEL, "Press \\B to cancel")
STRING(EOF_NO_RESULTS, "Reached end of file\nwith no results")
// Dumping
STRING(FLASHCARD_WILL_UNMOUNT, "Flashcard will be unmounted.\nIs this okay?")
STRING(DUMP_TO, "Dump \"%s\" to\n\"%s:/gm9i/out\"?")
STRING(DUMP_TO_GBA, "Dump \"%s\" to GBA cart?")
STRING(DUMP_ALL, "All")
STRING(DUMP_ALL_TRIMMED, "All (Trimmed ROM)")
STRING(DUMP_ROM, "ROM")
STRING(DUMP_ROM_TRIMMED, "ROM (Trimmed)")
STRING(DUMP_SAVE, "Save")
STRING(DUMP_DS_SAVE, "DS save")
STRING(DUMP_PUBLIC_SAVE, "Public save")
STRING(DUMP_PRIVATE_SAVE, "Private save")
STRING(DUMP_BANNER_SAVE, "Banner save")
STRING(DUMP_TMD, "TMD")
STRING(DUMP_METADATA, "Metadata")
STRING(DO_NOT_REMOVE_CARD, "Do not remove the NDS card.")
STRING(DO_NOT_REMOVE_CART, "Do not remove the GBA cart.")
STRING(DUMPING_SAVE, "Dumping save...")
STRING(RESTORING_SAVE, "Restoring save...")
STRING(DUMPING_METADATA, "Dumping metadata...")
STRING(FAILED_TO_DUMP_ROM, "Failed to dump the ROM.")
STRING(UNABLE_TO_DUMP_ROM, "Unable to dump the ROM.")
STRING(FAILED_TO_DUMP_SAVE, "Failed to dump the save.")
STRING(UNABLE_TO_DUMP_SAVE, "Unable to dump the save.")
STRING(FAILED_TO_RESTORE_SAVE, "Failed to restore the save.")
STRING(UNABLE_TO_RESTORE_SAVE, "Unable to restore the save.")
STRING(SAVE_SIZE_MISMATCH_CARD, "The size of this save doesn't match the size of the inserted game card.\n\nWrite cancelled!")
STRING(SAVE_SIZE_MISMATCH_CART, "The size of this save doesn't match the size of the inserted game pak.\n\nWrite cancelled!")
STRING(RESTORE_SELECTED_SAVE_CARD, "Restore the selected save to the inserted game card?")
STRING(RESTORE_SELECTED_SAVE_CARD_FLASHCARD, "Unmount the flashcard and restore the selected save to a game card?")
STRING(RESTORE_SELECTED_SAVE_CART, "Restore the selected save to the inserted game pak?")
STRING(EJECT_FLASHCARD_INSERT_GAME, "Eject your flashcard and insert the game card to restore to.")
STRING(PROGRESS, "Progress:")
STRING(N_OF_N_BYTES, "%d/%d Bytes")
STRING(NDS_IS_DUMPING, "%s.nds\nis dumping...")
STRING(GBA_IS_DUMPING, "%s.gba\nis dumping...")
STRING(COMPRESSING_SAVE, "Compressing save...")
STRING(WRITING_SAVE, "Writing save...")
STRING(WRITE_TO_GBA, "Write %s to GBA cart? (%s remaining)\n\nMake sure to back up your GBA save first!")
STRING(SWITCH_CART, "Please switch to a different GBA cart.")
STRING(SWITCH_CART_TO_SECTION, "Please switch to the GBA cart containing section %d.")
STRING(SWITCH_CART_TO_SECTION_THIS_WAS, "Please switch to the GBA cart containing section %d. (This was section %d)")
STRING(WRONG_DS_SAVE, "This cart contains a save file from a different DS game.")
STRING(NO_DS_SAVE, "This cart doesn't contain a DS save.")
STRING(PROGRESS, "Progress:")
// Confirmation/option button info
STRING(A_OK, "(\\A OK)")

View File

@ -112,7 +112,7 @@ int main(int argc, char **argv) {
bool yHeld = false;
// sprintf(titleName, "GodMode9i %s", VER_NUMBER);
sprintf(titleName, "GodMode9Nrio %s", "v3.4.3-NRIO");
sprintf(titleName, "GodMode9Nrio %s", "v3.4.4-NRIO");
// initialize video mode
videoSetMode(MODE_5_2D);

View File

@ -1,199 +0,0 @@
#include <nds.h>
#include <nds/fifocommon.h>
#include <nds/fifomessages.h>
#include <nds/disc_io.h>
#include <malloc.h>
#include <stdio.h>
#include "crypto.h"
#include "sector0.h"
#include "tonccpy.h"
#include "f_xy.h"
//#define SECTOR_SIZE 512
#define CRYPT_BUF_LEN 64
static u8* crypt_buf = 0;
static u32 fat_sig_fix_offset = 0;
static u32 sector_buf32[SECTOR_SIZE/sizeof(u32)];
static u8 *sector_buf = (u8*)sector_buf32;
static inline void nandio_set_fat_sig_fix(u32 offset) {
fat_sig_fix_offset = offset;
}
void getConsoleID(u8 *consoleID){
u8 *fifo=(u8*)0x02F00000; //shared mem address that has our computed key3 stuff
u8 key[16]; //key3 normalkey - keyslot 3 is used for DSi/twln NAND crypto
u8 key_xy[16]; //key3_y ^ key3_x
u8 key_x[16];////key3_x - contains a DSi console id (which just happens to be the LFCS on 3ds)
u8 key_y[16] = {0x76, 0xDC, 0xB9, 0x0A, 0xD3, 0xC4, 0x4D, 0xBD, 0x1D, 0xDD, 0x2D, 0x20, 0x05, 0x00, 0xA0, 0xE1}; //key3_y NAND constant
tonccpy(key, fifo, 16); //receive the goods from arm7
F_XY_reverse((uint32_t*)key, (uint32_t*)key_xy); //work backwards from the normalkey to get key_x that has the consoleID
for(int i=0;i<16;i++){
key_x[i] = key_xy[i] ^ key_y[i]; //''
}
tonccpy(&consoleID[0], &key_x[0], 4);
tonccpy(&consoleID[4], &key_x[0xC], 4);
}
//---------------------------------------------------------------------------------
bool my_nand_Startup() {
//---------------------------------------------------------------------------------
fifoSendValue32(FIFO_SDMMC,SDMMC_HAVE_SD);
while(!fifoCheckValue32(FIFO_SDMMC));
int result = fifoGetValue32(FIFO_SDMMC);
if(result==0) return false;
fifoSendValue32(FIFO_SDMMC,SDMMC_NAND_START);
fifoWaitValue32(FIFO_SDMMC);
result = fifoGetValue32(FIFO_SDMMC);
return result == 0;
}
//---------------------------------------------------------------------------------
bool my_nand_ReadSectors(sec_t sector, sec_t numSectors,void* buffer) {
//---------------------------------------------------------------------------------
FifoMessage msg;
DC_FlushRange(buffer,numSectors * 512);
msg.type = SDMMC_NAND_READ_SECTORS;
msg.sdParams.startsector = sector;
msg.sdParams.numsectors = numSectors;
msg.sdParams.buffer = buffer;
fifoSendDatamsg(FIFO_SDMMC, sizeof(msg), (u8*)&msg);
fifoWaitValue32(FIFO_SDMMC);
int result = fifoGetValue32(FIFO_SDMMC);
return result == 0;
}
bool nandio_startup() {
if (!my_nand_Startup()) return false;
my_nand_ReadSectors(0, 1, sector_buf);
bool isDSi = parse_ncsd(sector_buf, 0) != 0;
//if (!isDSi) return false;
if (*(u32*)(0x2FFD7BC) == 0) {
if (!isDSi) {
FILE* cidFile = fopen("sd:/gm9/out/nand_cid.mem", "rb");
if (!cidFile) return false;
fread((void*)0x2FFD7BC, 1, 16, cidFile);
fclose(cidFile);
} else {
// Get eMMC CID
*(u32*)(0xCFFFD0C) = 0x454D4D43;
while (*(u32*)(0xCFFFD0C) != 0) {
swiDelay(100);
}
}
}
u8 consoleID[8];
u8 consoleIDfixed[8];
// Get ConsoleID
getConsoleID(consoleID);
for (int i = 0; i < 8; i++) {
consoleIDfixed[i] = consoleID[7-i];
}
// iprintf("sector 0 is %s\n", is3DS ? "3DS" : "DSi");
dsi_crypt_init((const u8*)consoleIDfixed, (const u8*)0x2FFD7BC, !isDSi);
dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE);
parse_mbr(sector_buf, !isDSi, 0);
mbr_t *mbr = (mbr_t*)sector_buf;
nandio_set_fat_sig_fix(isDSi ? mbr->partitions[0].offset : 0);
if (crypt_buf == 0) {
crypt_buf = (u8*)memalign(32, SECTOR_SIZE * CRYPT_BUF_LEN);
//if (crypt_buf == 0) {
//printf("nandio: failed to alloc buffer\n");
//}
}
return crypt_buf != 0;
}
bool nandio_is_inserted() {
return true;
}
// len is guaranteed <= CRYPT_BUF_LEN
static bool read_sectors(sec_t start, sec_t len, void *buffer) {
if (my_nand_ReadSectors(start, len, crypt_buf)) {
dsi_nand_crypt(buffer, crypt_buf, start * SECTOR_SIZE / AES_BLOCK_SIZE, len * SECTOR_SIZE / AES_BLOCK_SIZE);
if (fat_sig_fix_offset &&
start == fat_sig_fix_offset
&& ((u8*)buffer)[0x36] == 0
&& ((u8*)buffer)[0x37] == 0
&& ((u8*)buffer)[0x38] == 0)
{
((u8*)buffer)[0x36] = 'F';
((u8*)buffer)[0x37] = 'A';
((u8*)buffer)[0x38] = 'T';
}
return true;
} else {
//printf("NANDIO: read error\n");
return false;
}
}
bool nandio_read_sectors(sec_t offset, sec_t len, void *buffer) {
// iprintf("R: %u(0x%08x), %u\n", (unsigned)offset, (unsigned)offset, (unsigned)len);
while (len >= CRYPT_BUF_LEN) {
if (!read_sectors(offset, CRYPT_BUF_LEN, buffer)) {
return false;
}
offset += CRYPT_BUF_LEN;
len -= CRYPT_BUF_LEN;
buffer = ((u8*)buffer) + SECTOR_SIZE * CRYPT_BUF_LEN;
}
if (len > 0) {
return read_sectors(offset, len, buffer);
} else {
return true;
}
}
bool nandio_write_sectors(sec_t offset, sec_t len, const void *buffer) {
// lol, nope
return false;
}
bool nandio_clear_status() {
return true;
}
bool nandio_shutdown() {
free(crypt_buf);
crypt_buf = 0;
return true;
}
const DISC_INTERFACE io_dsi_nand = {
('N' << 24) | ('A' << 16) | ('N' << 8) | 'D',
FEATURE_MEDIUM_CANREAD,
nandio_startup,
nandio_is_inserted,
nandio_read_sectors,
nandio_write_sectors,
nandio_clear_status,
nandio_shutdown
};

View File

@ -1,8 +0,0 @@
#pragma once
#include <nds.h>
#include <nds/disc_io.h>
void nandio_set_fat_sig_fix(u32 offset);
extern const DISC_INTERFACE io_dsi_nand;

View File

@ -1,102 +0,0 @@
#include <nds.h>
#include <nds/ndstypes.h>
#include <nds/disc_io.h>
#include "tonccpy.h"
#define SECTOR_SIZE 512
const static u8 bootSector[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, SECTOR_SIZE & 0xFF, SECTOR_SIZE >> 8, 0x04, 0x01, 0x00,
0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 'R', 'A', 'M', 'D', 'R',
'I', 'V', 'E', ' ', ' ', ' ', 'F', 'A', 'T'
};
u32 ramdSectors = 0;
u8* ramdLoc = (u8*)NULL;
u8* ramdLocMep = (u8*)NULL;
const u16 bootSectorSignature = 0xAA55;
bool ramd_startup() {
if(isDSiMode() || REG_SCFG_EXT != 0) {
ramdLoc = (u8*)malloc(0x6000 * SECTOR_SIZE);
} else {
ramdLoc = (u8*)calloc(0x8 * SECTOR_SIZE, 1);
toncset(ramdLocMep, 0, (ramdSectors - 0x8) * SECTOR_SIZE); // Fill MEP with 00 to avoid displaying weird files
}
tonccpy(ramdLoc, bootSector, sizeof(bootSector));
tonccpy(ramdLoc + 0x20, &ramdSectors, 4);
tonccpy(ramdLoc + 0x1FE, &bootSectorSignature, 2);
return true;
}
bool ramd_is_inserted() {
return isDSiMode() || REG_SCFG_EXT != 0 || *(u16*)(0x020000C0) != 0 || *(vu16*)(0x08240000) == 1;
}
bool ramd_read_sectors(sec_t sector, sec_t numSectors, void *buffer) {
for(int i = 0; i < numSectors; i++, sector++) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
if(sector < 0x6000) {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= 0xE000) {
tonccpy(buffer + (i * SECTOR_SIZE), (void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), SECTOR_SIZE);
}
} else if(sector < 0x8) {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLoc + (sector * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= ramdSectors - 0x8) {
tonccpy(buffer + (i * SECTOR_SIZE), ramdLocMep + ((sector - 0x8) * SECTOR_SIZE), SECTOR_SIZE);
} else {
return false;
}
}
return true;
}
bool ramd_write_sectors(sec_t sector, sec_t numSectors, const void *buffer) {
for(int i = 0; i < numSectors; i++, sector++) {
if(isDSiMode() || REG_SCFG_EXT != 0) {
if(sector < 0x6000) {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= 0xE000) {
tonccpy((void*)0x0D000000 + ((sector - 0x6000) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
}
} else if(sector < 0x8) {
tonccpy(ramdLoc + (sector * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else if(sector <= ramdSectors - 0x8) {
tonccpy(ramdLocMep + ((sector - 0x8) * SECTOR_SIZE), buffer + (i * SECTOR_SIZE), SECTOR_SIZE);
} else {
return false;
}
}
return true;
}
bool ramd_clear_status() {
return true;
}
bool ramd_shutdown() {
if(ramdLoc) {
free(ramdLoc);
ramdLoc = NULL;
}
return true;
}
const DISC_INTERFACE io_ram_drive = {
('R' << 24) | ('A' << 16) | ('M' << 8) | '1',
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE,
ramd_startup,
ramd_is_inserted,
ramd_read_sectors,
ramd_write_sectors,
ramd_clear_status,
ramd_shutdown
};

View File

@ -1,10 +0,0 @@
#pragma once
#include <nds.h>
#include <nds/ndstypes.h>
#include <nds/disc_io.h>
extern u32 ramdSectors;
extern u8* ramdLocMep;
extern const DISC_INTERFACE io_ram_drive;

View File

@ -1,102 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "utils.h"
#include "sector0.h"
// return 0 for valid NCSD header
int parse_ncsd(const uint8_t sector0[SECTOR_SIZE], int verbose) {
const ncsd_header_t * h = (ncsd_header_t *)sector0;
if (h->magic == 0x4453434e) {
if (verbose) {
//printf("NCSD magic found\n");
}
} else {
if (verbose) {
//printf("NCSD magic not found\n");
}
return -1;
}
if (verbose) {
//iprintf("size: %" PRIu32 " sectors, %s MB\n", h->size, to_mebi(h->size * SECTOR_SIZE));
//iprintf("media ID: %08" PRIx32 "%08" PRIx32 "\n", h->media_id_h, h->media_id_l);
}
for (unsigned i = 0; i < NCSD_PARTITIONS; ++i) {
unsigned fs_type = h->fs_types[i];
if (fs_type == 0) {
break;
}
const char *s_fs_type;
switch (fs_type) {
case 1:
s_fs_type = "Normal";
break;
case 3:
s_fs_type = "FIRM";
break;
case 4:
s_fs_type = "AGB_FIRM save";
break;
default:
if (verbose) {
//iprintf("invalid partition type %d\n", fs_type);
}
return -2;
}
if (verbose) {
// yes I use MB for "MiB", bite me
//iprintf("partition %u, %s, crypt: %" PRIu8 ", offset: 0x%08" PRIx32 ", length: 0x%08" PRIx32 "(%s MB)\n",
//i, s_fs_type, h->crypt_types[i],
//h->partitions[i].offset, h->partitions[i].length, to_mebi(h->partitions[i].length * SECTOR_SIZE));
}
}
return 0;
}
const mbr_partition_t ptable_DSi[MBR_PARTITIONS] = {
{0, {3, 24, 4}, 6, {15, 224, 59}, 0x00000877, 0x00066f89},
{0, {2, 206, 60}, 6, {15, 224, 190}, 0x0006784d, 0x000105b3},
{0, {2, 222, 191}, 1, {15, 224, 191}, 0x00077e5d, 0x000001a3},
{0, {0, 0, 0}, 0, {0, 0, 0}, 0, 0}
};
const mbr_partition_t ptable_3DS[MBR_PARTITIONS] = {
{0, {4, 24, 0}, 6, {1, 160, 63}, 0x00000097, 0x00047da9},
{0, {4, 142, 64}, 6, {1, 160, 195}, 0x0004808d, 0x000105b3},
{0, {0, 0, 0}, 0, {0, 0, 0}, 0, 0},
{0, {0, 0, 0}, 0, {0, 0, 0}, 0, 0}
};
// return 0 for valid MBR
int parse_mbr(const uint8_t sector0[SECTOR_SIZE], int is3DS, int verbose) {
const mbr_t *m = (mbr_t*)sector0;
const mbr_partition_t *ref_ptable; // reference partition table
int ret = 0;
if (m->boot_signature_0 != 0x55 || m->boot_signature_1 != 0xaa) {
//printf("invalid boot signature(0x55, 0xaa)\n");
ret = -1;
}
if (!is3DS) {
for (unsigned i = 0; i < sizeof(m->bootstrap); ++i) {
if (m->bootstrap[i]) {
//printf("bootstrap on DSi should be all zero\n");
ret = 0;
break;
}
}
ref_ptable = ptable_DSi;
} else {
ref_ptable = ptable_3DS;
}
// Only check the first two as those are the only ones we mount
// There's some variation in the 3rd
for(int i = 0; i < 2; i++) {
if (memcmp(&ref_ptable[i], &m->partitions[i], sizeof(mbr_partition_t))) {
//printf("invalid partition table\n");
ret = -2;
}
}
return ret;
}

View File

@ -1,72 +0,0 @@
#pragma once
#include <stdint.h>
#include <assert.h>
// https://3dbrew.org/wiki/NCSD#NCSD_header
#define SECTOR_SIZE 0x200
#define NCSD_PARTITIONS 8
#ifdef _MSC_VER
#pragma pack(push, 1)
#define __PACKED
#elif defined __GNUC__
#define __PACKED __attribute__ ((__packed__))
#endif
typedef struct {
uint32_t offset;
uint32_t length;
} __PACKED ncsd_partition_t;
typedef struct {
uint8_t signature[0x100];
uint32_t magic;
uint32_t size;
uint32_t media_id_l;
uint32_t media_id_h;
uint8_t fs_types[NCSD_PARTITIONS];
uint8_t crypt_types[NCSD_PARTITIONS];
ncsd_partition_t partitions[NCSD_PARTITIONS];
} __PACKED ncsd_header_t;
typedef struct {
uint8_t head;
uint8_t sector;
uint8_t cylinder;
} __PACKED chs_t;
typedef struct {
uint8_t status;
chs_t chs_first;
uint8_t type;
chs_t chs_last;
uint32_t offset;
uint32_t length;
} __PACKED mbr_partition_t;
#define MBR_PARTITIONS 4
// or 446 in decimal, all zero on DSi in all my samples
#define MBR_BOOTSTRAP_SIZE 0x1be
typedef struct {
uint8_t bootstrap[MBR_BOOTSTRAP_SIZE];
mbr_partition_t partitions[MBR_PARTITIONS];
uint8_t boot_signature_0;
uint8_t boot_signature_1;
} __PACKED mbr_t;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
#undef __PACKED
static_assert(sizeof(ncsd_header_t) == 0x160, "sizeof(ncsd_header_t) should equal 0x160");
static_assert(sizeof(mbr_t) == SECTOR_SIZE, "sizeof(mbr_t) should equal 0x200");
int parse_ncsd(const uint8_t sector0[SECTOR_SIZE], int verbose);
int parse_mbr(const uint8_t sector0[SECTOR_SIZE], int is3DS, int verbose);

View File

@ -6,7 +6,6 @@
#include "language.h"
#include "main.h"
#include "screenshot.h"
#include "titleManager.h"
#include <array>
#include <nds.h>
@ -17,14 +16,12 @@
enum class StartMenuItem : u8 {
powerOff = 0,
reboot = 1,
titleManager = 2,
langauge = 3,
langauge = 2,
};
constexpr std::array<std::string *, 4> startMenuStrings = {
&STR_POWER_OFF,
&STR_REBOOT,
&STR_OPEN_TITLE_MANAGER,
&STR_LANGUAGE
};
@ -56,8 +53,6 @@ void startMenu() {
StartMenuItem::powerOff,
StartMenuItem::reboot
};
if(nandMounted && (sdMounted || flashcardMounted))
startMenuItems.push_back(StartMenuItem::titleManager);
startMenuItems.push_back(StartMenuItem::langauge);
} else {
startMenuItems = {
@ -104,9 +99,6 @@ void startMenu() {
fifoSendValue32(FIFO_USER_02, 1);
while(1) swiWaitForVBlank();
break;
case StartMenuItem::titleManager:
titleManager();
break;
case StartMenuItem::langauge:
languageMenu();
break;

View File

@ -1,340 +0,0 @@
#include "titleManager.h"
#include "config.h"
#include "driveOperations.h"
#include "file_browse.h"
#include "fileOperations.h"
#include "font.h"
#include "language.h"
#include "main.h"
#include "screenshot.h"
#include <algorithm>
#include <dirent.h>
#include <nds.h>
#include <unistd.h>
#include <vector>
struct TitleInfo {
TitleInfo(std::string path, const char *gameTitle, const char *gameCode, u8 *appVersion, u8 romVersion, std::u16string bannerTitle) : path(path), romVersion(romVersion), bannerTitle(bannerTitle) {
strcpy(this->gameTitle, gameTitle);
strcpy(this->gameCode, gameCode);
tonccpy(this->appVersion, appVersion, 4);
}
std::string path;
char gameTitle[13];
char gameCode[7];
u8 appVersion[4];
u8 romVersion;
std::u16string bannerTitle;
};
enum TitleDumpOption {
none = 0,
rom = 1,
publicSave = 4,
privateSave = 8,
bannerSave = 16,
tmd = 32,
all = rom | publicSave | privateSave | bannerSave | tmd
};
void dumpTitle(TitleInfo &title) {
u16 pressed = 0, held = 0;
int optionOffset = 0;
std::vector<TitleDumpOption> allowedOptions({TitleDumpOption::all, TitleDumpOption::rom});
u8 allowedBitfield = TitleDumpOption::rom | TitleDumpOption::tmd;
if(access((title.path + "/data/public.sav").c_str(), F_OK) == 0) {
allowedOptions.push_back(TitleDumpOption::publicSave);
allowedBitfield |= TitleDumpOption::publicSave;
}
if(access((title.path + "/data/private.sav").c_str(), F_OK) == 0) {
allowedOptions.push_back(TitleDumpOption::privateSave);
allowedBitfield |= TitleDumpOption::privateSave;
}
if(access((title.path + "/data/banner.sav").c_str(), F_OK) == 0) {
allowedOptions.push_back(TitleDumpOption::bannerSave);
allowedBitfield |= TitleDumpOption::bannerSave;
}
allowedOptions.push_back(TitleDumpOption::tmd);
char dumpName[32];
snprintf(dumpName, sizeof(dumpName), "%s_%s_%02X", title.gameTitle, title.gameCode, title.romVersion);
char dumpToStr[256];
snprintf(dumpToStr, sizeof(dumpToStr), STR_DUMP_TO.c_str(), dumpName, sdMounted ? "sd" : "fat");
int y = font->calcHeight(dumpToStr) + 1;
while (true) {
font->clear(false);
font->print(firstCol, 0, false, dumpToStr, alignStart);
int optionsCol = rtl ? -4 : 3;
int row = y;
for(TitleDumpOption option : allowedOptions) {
switch(option) {
case TitleDumpOption::all:
font->print(optionsCol, row++, false, STR_DUMP_ALL, alignStart);
break;
case TitleDumpOption::rom:
font->print(optionsCol, row++, false, STR_DUMP_ROM, alignStart);
break;
case TitleDumpOption::publicSave:
font->print(optionsCol, row++, false, STR_DUMP_PUBLIC_SAVE, alignStart);
break;
case TitleDumpOption::privateSave:
font->print(optionsCol, row++, false, STR_DUMP_PRIVATE_SAVE, alignStart);
break;
case TitleDumpOption::bannerSave:
font->print(optionsCol, row++, false, STR_DUMP_BANNER_SAVE, alignStart);
break;
case TitleDumpOption::tmd:
font->print(optionsCol, row++, false, STR_DUMP_TMD, alignStart);
break;
case TitleDumpOption::none:
row++;
break;
}
}
font->print(optionsCol, ++row, false, STR_A_SELECT_B_CANCEL, alignStart);
// Show cursor
font->print(firstCol, y + optionOffset, false, rtl ? "<-" : "->", alignStart);
font->update(false);
// Power saving loop. Only poll the keys once per frame and sleep the CPU if there is nothing else to do
do {
scanKeys();
pressed = keysDownRepeat();
held = keysHeld();
swiWaitForVBlank();
} while (!(pressed & (KEY_UP| KEY_DOWN | KEY_A | KEY_B | KEY_L | config->screenSwapKey())));
if (pressed & KEY_UP)
optionOffset--;
if (pressed & KEY_DOWN)
optionOffset++;
if (optionOffset < 0) // Wrap around to bottom of list
optionOffset = allowedOptions.size() - 1;
if (optionOffset >= (int)allowedOptions.size()) // Wrap around to top of list
optionOffset = 0;
if (pressed & KEY_A) {
TitleDumpOption selectedOption = allowedOptions[optionOffset];
// Ensure directories exist
char folderPath[16];
sprintf(folderPath, "%s:/gm9i", (sdMounted ? "sd" : "fat"));
if (access(folderPath, F_OK) != 0) {
font->clear(false);
font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart);
font->update(false);
mkdir(folderPath, 0777);
}
sprintf(folderPath, "%s:/gm9i/out", (sdMounted ? "sd" : "fat"));
if (access(folderPath, F_OK) != 0) {
font->clear(false);
font->print(firstCol, 0, false, STR_CREATING_DIRECTORY, alignStart);
font->update(false);
mkdir(folderPath, 0777);
}
// Dump to /gm9i/out
char inpath[64], outpath[64];
if((selectedOption & TitleDumpOption::rom) && (allowedBitfield & TitleDumpOption::rom)) {
snprintf(inpath, sizeof(inpath), "%s/content/%02x%02x%02x%02x.app", title.path.c_str(), title.appVersion[0], title.appVersion[1], title.appVersion[2], title.appVersion[3]);
snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.nds", sdMounted ? "sd" : "fat", dumpName);
fcopy(inpath, outpath);
}
if((selectedOption & TitleDumpOption::publicSave) && (allowedBitfield & TitleDumpOption::publicSave)) {
snprintf(inpath, sizeof(inpath), "%s/data/public.sav", title.path.c_str());
snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.pub", sdMounted ? "sd" : "fat", dumpName);
fcopy(inpath, outpath);
}
if((selectedOption & TitleDumpOption::privateSave) && (allowedBitfield & TitleDumpOption::privateSave)) {
snprintf(inpath, sizeof(inpath), "%s/data/private.sav", title.path.c_str());
snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.prv", sdMounted ? "sd" : "fat", dumpName);
fcopy(inpath, outpath);
}
if((selectedOption & TitleDumpOption::bannerSave) && (allowedBitfield & TitleDumpOption::bannerSave)) {
snprintf(inpath, sizeof(inpath), "%s/data/banner.sav", title.path.c_str());
snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.bnr", sdMounted ? "sd" : "fat", dumpName);
fcopy(inpath, outpath);
}
if((selectedOption & TitleDumpOption::tmd) && (allowedBitfield & TitleDumpOption::tmd)) {
snprintf(inpath, sizeof(inpath), "%s/content/title.tmd", title.path.c_str());
snprintf(outpath, sizeof(outpath), "%s:/gm9i/out/%s.tmd", sdMounted ? "sd" : "fat", dumpName);
fcopy(inpath, outpath);
}
return;
}
if (pressed & KEY_B)
return;
// Swap screens
if (pressed & config->screenSwapKey()) {
screenSwapped = !screenSwapped;
screenSwapped ? lcdMainOnBottom() : lcdMainOnTop();
}
// Make a screenshot
if ((held & KEY_R) && (pressed & KEY_L)) {
screenshot();
}
}
}
void titleManager() {
if(!nandMounted || !(sdMounted || flashcardMounted))
return;
char oldPath[PATH_MAX];
getcwd(oldPath, PATH_MAX);
std::vector<TitleInfo> titles;
for(u32 tidHigh : {0x00030004, 0x00030005, 0x00030015, 0x00030017}) {
char path[64];
snprintf(path, sizeof(path), "nand:/title/%08lx", tidHigh);
if(access(path, F_OK) == 0) {
chdir(path);
std::vector<DirEntry> dirContents;
getDirectoryContents(dirContents);
for(const DirEntry &entry : dirContents) {
if(entry.name[0] == '.')
continue;
u8 appVersion[4];
snprintf(path, sizeof(path), "nand:/title/%08lx/%s/content/title.tmd", tidHigh, entry.name.c_str());
FILE *tmd = fopen(path, "rb");
if(tmd) {
fseek(tmd, 0x1E4, SEEK_SET);
fread(appVersion, 1, 4, tmd);
fclose(tmd);
snprintf(path, sizeof(path), "nand:/title/%08lx/%s/content/%02x%02x%02x%02x.app", tidHigh, entry.name.c_str(), appVersion[0], appVersion[1], appVersion[2], appVersion[3]);
FILE *app = fopen(path, "rb");
if(app) {
char gameTitle[13] = {0};
char gameCode[7] = {0};
u8 romVersion;
fread(gameTitle, 1, 12, app);
fread(gameCode, 1, 6, app);
fseek(app, 12, SEEK_CUR);
fread(&romVersion, 1, 1, app);
u32 ofs;
char16_t title[0x80];
fseek(app, 0x68, SEEK_SET);
fread(&ofs, sizeof(u32), 1, app);
if(ofs >= 0x8000 && fseek(app, ofs, SEEK_SET) == 0) {
fseek(app, 0x240 + (0x80 * 2), SEEK_CUR);
fread(title, 2, 0x80, app);
} else {
title[0] = u'\0';
}
fclose(app);
snprintf(path, sizeof(path), "nand:/title/%08lx/%s", tidHigh, entry.name.c_str());
titles.emplace_back(path, gameTitle, gameCode, appVersion, romVersion, title);
}
}
}
}
}
chdir(oldPath);
// Sort alphabetically by banner title
std::sort(titles.begin(), titles.end(), [](TitleInfo lhs, TitleInfo rhs) {
for(size_t i = 0; i < lhs.bannerTitle.length(); i++) {
char16_t lchar = tolower(lhs.bannerTitle[i]);
char16_t rchar = tolower(rhs.bannerTitle[i]);
if(lchar == u'\0')
return true;
else if(rchar == u'\0')
return false;
else if(lchar < rchar)
return true;
else if(lchar > rchar)
return false;
}
return false;
});
u16 pressed = 0, held = 0;
int cursorPosition = 0, scrollOffset = 0;
while(1) {
font->clear(false);
font->printf(firstCol, 0, false, alignStart, Palette::blackGreen, "%*c", SCREEN_COLS, ' ');
font->print(0, 0, false, STR_TITLE_MANAGER, Alignment::center, Palette::blackGreen);
for(int i = 0; i < ((int)titles.size() - scrollOffset) && i < ENTRIES_PER_SCREEN; i++) {
const TitleInfo &title = titles[scrollOffset + i];
Palette pal = scrollOffset + i == cursorPosition ? Palette::white : Palette::gray;
font->print(firstCol, 1 + i, false, title.bannerTitle.substr(0, title.bannerTitle.find(u'\n')), alignStart, pal);
font->printf(lastCol, 1 + i, false, alignEnd, pal, rtl ? "(%s) " : " (%s)", title.gameCode);
}
font->update(false);
do {
swiWaitForVBlank();
scanKeys();
pressed = keysDown();
held = keysDownRepeat();
} while(!(held & (KEY_UP | KEY_DOWN | KEY_LEFT | KEY_RIGHT | KEY_A | KEY_B | KEY_L | config->screenSwapKey())));
if(held & KEY_UP) {
cursorPosition--;
if(cursorPosition < 0)
cursorPosition = titles.size() - 1;
} else if(held & KEY_DOWN) {
cursorPosition++;
if(cursorPosition > (int)titles.size() - 1)
cursorPosition = 0;
} else if(held & KEY_LEFT) {
cursorPosition -= ENTRIES_PER_SCREEN;
if(cursorPosition < 0)
cursorPosition = 0;
} else if(held & KEY_RIGHT) {
cursorPosition += ENTRIES_PER_SCREEN;
if(cursorPosition > (int)titles.size() + 1)
cursorPosition = titles.size() - 1;
} else if(pressed & KEY_A) {
dumpTitle(titles[cursorPosition]);
} else if(pressed & KEY_B) {
return;
}
// Scroll screen if needed
if (cursorPosition < scrollOffset)
scrollOffset = cursorPosition;
if (cursorPosition > scrollOffset + ENTRIES_PER_SCREEN - 1)
scrollOffset = cursorPosition - ENTRIES_PER_SCREEN + 1;
// Swap screens
if (pressed & config->screenSwapKey()) {
screenSwapped = !screenSwapped;
screenSwapped ? lcdMainOnBottom() : lcdMainOnTop();
}
if((pressed & KEY_L) && (keysHeld() & KEY_R)) {
screenshot();
}
}
}

View File

@ -1,6 +0,0 @@
#ifndef TITLE_MANAGER_H
#define TITLE_MANAGER_H
void titleManager(void);
#endif // TITLE_MANAGER_H

View File

@ -1,195 +0,0 @@
#include <stdio.h>
#include <sys/statvfs.h>
#include <nds.h>
#include "my_sha1.h"
#include "utils.h"
swiSHA1context_t sha1ctx;
static inline int htoi(char a){
if(a >= '0' && a <= '9'){
return a - '0';
}else if(a >= 'a' && a <= 'f'){
return a - ('a' - 0xa);
}else if(a >= 'A' && a <= 'F'){
return a - ('A' - 0xa);
}else{
return -1;
}
}
int hex2bytes(uint8_t *out, unsigned byte_len, const char *in){
if (strlen(in) < byte_len << 1){
iprintf("%s: invalid input length, expecting %u, got %u.\n",
__FUNCTION__, (unsigned)byte_len << 1, (unsigned)strlen(in));
return -1;
}
for(unsigned i = 0; i < byte_len; ++i){
int h = htoi(*in++), l = htoi(*in++);
if(h == -1 || l == -1){
iprintf("%s: invalid input \"%c%c\"\n",
__FUNCTION__, *(in - 2), *(in - 1));
return -2;
}
*out++ = (h << 4) + l;
}
return 0;
}
static char str_buf[0x10];
const char *to_mebi(size_t size) {
if (size % (1024 * 1024)) {
sprintf(str_buf, "%.2f", (float)(((double)size) / 1024 / 1024));
} else {
siprintf(str_buf, "%u", (unsigned)(size >> 20));
}
return str_buf;
}
int save_file(const char *filename, const void *buffer, size_t size, int save_sha1) {
FILE *f = fopen(filename, "wb");
if (f == 0) {
//iprintf("failed to open %s to write\n", filename);
return -1;
}
size_t written = fwrite(buffer, 1, size, f);
fclose(f);
if (written != size) {
//iprintf("error writting %s\n", filename);
return -2;
} else {
//iprintf("saved %s\n", filename);
}
if (save_sha1) {
sha1ctx.sha_block = 0;
my_swiSHA1Init(&sha1ctx);
my_swiSHA1Update(&sha1ctx, buffer, size);
save_sha1_file(filename);
}
return 0;
}
int load_file(void **pbuf, size_t *psize, const char *filename, int verify_sha1, int align) {
FILE *f = fopen(filename, "rb");
if (f == 0) {
//iprintf("failed to open %s to read\n", filename);
return -1;
}
int ret;
fseek(f, 0, SEEK_END);
*psize = ftell(f);
if (*psize == 0) {
*pbuf = 0;
ret = 1;
} else {
if (align) {
*pbuf = memalign(align, *psize);
} else {
*pbuf = malloc(*psize);
}
if (*pbuf == 0) {
//printf("failed to alloc memory\n");
ret = -1;
} else {
fseek(f, 0, SEEK_SET);
unsigned read = fread(*pbuf, 1, *psize, f);
if (read != *psize) {
//iprintf("error reading %s\n", filename);
free(*pbuf);
*pbuf = 0;
ret = -2;
} else {
//iprintf("loaded %s(%u)\n", filename, read);
if (verify_sha1) {
//TODO:
//iprintf("%s: not implemented\n", __FUNCTION__);
}
ret = 0;
}
}
}
fclose(f);
return ret;
}
int load_block_from_file(void *buf, const char *filename, unsigned offset, unsigned size) {
FILE *f = fopen(filename, "rb");
if (f == 0) {
//iprintf("failed to open %s\n", filename);
return -1;
}
unsigned read;
int ret;
if (offset != 0 && fseek(f, offset, SEEK_SET) != 0) {
//printf("seek error\n");
ret = -1;
} else if ((read = fread(buf, 1, size, f)) != size) {
//iprintf("read error, expecting %u, got %u\n", size, read);
ret = -1;
} else {
ret = 0;
}
fclose(f);
return ret;
}
// you should have updated the sha1 context before calling save_sha1_file
// example: save_file() in this file and backup() in nand.c
int save_sha1_file(const char *filename) {
size_t len_fn = strlen(filename);
char *sha1_fn = (char *)malloc(len_fn + 6);
siprintf(sha1_fn, "%s.sha1", filename);
// 20 bytes each use 2 chars, space, asterisk, filename, new line
size_t len_buf = 2 * 20 + 1 + 1 + len_fn + 1;
char *sha1_buf = (char *)malloc(len_buf + 1); // extra for \0
char *p = sha1_buf;
char *digest = (char *)malloc(20);
my_swiSHA1Final(digest, &sha1ctx);
for (int i = 0; i < 20; ++i) {
p += siprintf(p, "%02X", digest[i]);
}
free(digest);
siprintf(p, " *%s\n", filename);
int ret = save_file(sha1_fn, (u8*)sha1_buf, len_buf, false);
free(sha1_fn);
free(sha1_buf);
return ret;
}
void print_bytes(const void *buf, size_t len) {
const unsigned char *p = (const unsigned char *)buf;
for(size_t i = 0; i < len; ++i) {
iprintf("%02x", *p++);
}
}
// out must be big enough
// can work in place
void utf16_to_ascii(uint8_t *out, const uint16_t *in, unsigned len) {
const uint16_t *end = in + len;
while (in < end){
uint16_t c = *in++;
if (c == 0) {
*out = 0;
break;
} else if (c < 0x80) {
*out++ = (uint8_t)c;
}
}
}
size_t df(const char *path, int verbose) {
// it's amazing libfat even got this to work
struct statvfs s;
statvfs(path, &s);
size_t free = s.f_bsize * s.f_bfree;
if (verbose) {
//iprintf("%s", to_mebi(free));
//iprintf("/%s MB (free/total)\n", to_mebi(s.f_bsize * s.f_blocks));
}
return free;
}

View File

@ -1,23 +0,0 @@
#pragma once
#include <nds.h>
#include <stdint.h>
int hex2bytes(uint8_t *out, unsigned byte_len, const char *in);
const char * to_mebi(size_t size);
int save_file(const char *filename, const void *buffer, size_t size, int save_sha1);
int load_file(void **pbuf, size_t *psize, const char *filename, int verify_sha1, int align);
int load_block_from_file(void *buf, const char *filename, unsigned offset, unsigned size);
int save_sha1_file(const char *filename);
void print_bytes(const void *buf, size_t len);
void utf16_to_ascii(uint8_t *out, const uint16_t *in, unsigned len);
size_t df(const char *path, int verbose);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,85 +1,13 @@
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
*/build
*.dsi
*.nds
*.cia
*.d
*.elf
*.cmd
data/*.bin
title/
.vscode
*.DS_Store
arm9/include/version.h

File diff suppressed because it is too large Load Diff

View File

@ -128,9 +128,6 @@ $(OUTPUT).elf : $(OFILES)
topLoad.s : ../$(IMAGES)/topLoad.bmp
grit $< -gB8 -gzl -fts -gTff00ff -o $@ -q
subLoad.s : ../$(IMAGES)/subLoad.bmp
grit $< -gB8 -gzl -fts -gTff00ff -o $@ -q
topError.s : ../$(IMAGES)/topError.bmp
grit $< -gB8 -gzl -fts -gTff00ff -o $@ -q

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
extern const u8 load_bin_end[];
extern const u8 load_bin[];
extern const u32 load_bin_size;

View File

@ -1,29 +0,0 @@
//{{BLOCK(subError)
//======================================================================
//
// subError, 256x192@8,
// Transparent color : FF,00,FF
// + palette 256 entries, not compressed
// + 768 tiles lz77 compressed
// Total size: 512 + 6860 = 7372
//
// Time-stamp: 2023-11-03, 21:08:29
// Exported by Cearn's GBA Image Transmogrifier, v0.8.14
// ( http://www.coranac.com/projects/#grit )
//
//======================================================================
#ifndef GRIT_SUBERROR_H
#define GRIT_SUBERROR_H
#define subErrorTilesLen 6860
extern const unsigned int subErrorTiles[1715];
#define subErrorPalLen 512
extern const unsigned short subErrorPal[256];
#endif // GRIT_SUBERROR_H
//}}BLOCK(subError)

View File

@ -1,306 +0,0 @@
@{{BLOCK(subError)
@=======================================================================
@
@ subError, 256x192@8,
@ Transparent color : FF,00,FF
@ + palette 256 entries, not compressed
@ + 768 tiles lz77 compressed
@ Total size: 512 + 6860 = 7372
@
@ Time-stamp: 2023-11-03, 21:08:29
@ Exported by Cearn's GBA Image Transmogrifier, v0.8.14
@ ( http://www.coranac.com/projects/#grit )
@
@=======================================================================
.section .rodata
.align 2
.global subErrorTiles @ 6860 unsigned chars
.hidden subErrorTiles
subErrorTiles:
.word 0x00C00010,0xF0FFFF3F,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FC01F0,0xF001F001,0xF001F001,0xAF077001,0x133090AF,0x08200707,0x575707AF
.word 0x57241085,0x2007AF57,0x0210AF16,0x101600E6,0x07160012,0x10010007,0xAF73AF16,0x4EF02A00
.word 0xAF570950,0x56302A00,0x202720FF,0x20075044,0xF0543040,0x209A8001,0x9200DF41,0x5057A330
.word 0x205930A9,0x4001F097,0x8220FFD5,0x7A10CB00,0x7250D900,0x3FF08A50,0x30FFC0F0,0x101721DE
.word 0x40522039,0x10C04035,0xEF01F007,0x28015521,0x01AF2820,0x11610107,0xFF2E1153,0x58019720
.word 0x3EF14420,0xA4407DF0,0xBB70B3D0,0xF0C450DF,0x60200721,0x80F180F1,0x0F1201F0,0x026F21FB
.word 0x417F0107,0x5719128E,0x08127E01,0xF00340FF,0x314E5201,0x113E0028,0x41EB60B7,0xD631FF17
.word 0x43D136F0,0x7820FE41,0x02F16D40,0x21F701F0,0x210011FF,0x57C210FA,0x7B01AD30,0xF0FF9740
.word 0x007DF23F,0x803E3034,0xF07EF0EC,0xFF402301,0x6FF10522,0x01F07FF1,0x77F001F2,0x3DF07FF0
.word 0x334003FF,0x03C231BC,0x52944140,0x9238F09C,0xBA12FF4D,0x7F230D04,0x4B330D04,0x23303871
.word 0x91FF7EF2,0xF0FC22DC,0x747BC01F,0xA024F083,0xFF835107,0x86042760,0x8C521354,0xAE24D550
.word 0x8623E540,0x339532FF,0xF0B550D4,0xA17A54FA,0x1424253E,0x3EF1FF7F,0x7F5401F0,0x4C050213
.word 0x77020233,0x93FF0354,0xB339F002,0xF37D0541,0xF3172041,0xFF01F041,0xCB054F41,0x17509CC5
.word 0xBE6532F0,0xFB23C335,0x234284FF,0x85D024FB,0x3101F048,0x04FA14C9,0x3F32FFE4,0x08118043
.word 0x3FF29C33,0x3FF23FF2,0xF0FF3FF2,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xD0F104D6,0xB501F0FF,0x308642E5,0xF054F138,0xF428F401,0x01F0FFCE
.word 0x8DE201F0,0x1EF05C28,0x67B701F0,0xF0FFE053,0xF001F0BD,0xF0D7C701,0xD101F001,0xFF1E273F
.word 0x40F01719,0x7DF001F0,0x01F0CEF2,0x80F101F0,0xF080F1FF,0x6901F001,0x63D81914,0xF001F06C
.word 0x2774FF01,0x6916301A,0x01F07CF0,0x0E6901F0,0xF0FF5B2A,0xC601F01E,0x399E28A7,0xF03FF057
.word 0xFFA5D701,0xC2F1BE31,0x01F001F0,0x111B9356,0xC9626B17,0xF001F0FF,0xF001F201,0xF001F01D
.word 0x73D4783D,0x01F0FF49,0x406301F0,0xFD2B8F1A,0x01F07FF3,0x3BFF24E9,0xFAE42A54,0xF001F0D0
.word 0xF003F101,0xFF01F001,0xCFF7C6F4,0xBFF001F0,0x21F080C2,0x3ED101F0,0x1C3B22FF,0xF07FF262
.word 0xF325EA01,0xF001F041,0x3EF1FF01,0x01F0BFF0,0x105D01F0,0x7EF1292B,0xF2FF01F0,0x2E4D3800
.word 0xF07FF020,0xA73FF201,0xFF01F0E7,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x3DFE3DFE,0x63353D7E,0x1AFFE643
.word 0xF00750CB,0xFEFFFE52,0xF0FF7EFF,0xFFD5867F,0xDF253E1A,0x3E2A4320,0xAD52A552,0x49A43FF0
.word 0x6BD155FF,0x3469F429,0x80153C04,0x6F353C5C,0x74A0FF42,0xFAF08480,0x810FA98C,0xF75AFFAA
.word 0x5BFFD71E,0xB901F007,0x575245D0,0x1D62D5D9,0xFF6B4C00,0x24619A6B,0x2C517C1C,0xE725451C
.word 0x7BF0D741,0x4CC0F1FF,0x4F7C71FB,0xF0448F34,0x3C178838,0x022CFF26,0x661A3E2E,0x6E2A460E
.word 0xAFF60D20,0x11FF3D8F,0x2160023D,0x2D3A0CFE,0x22A9347D,0xFFC1F09A,0x3FFF01FF,0x433107F0
.word 0x0652704D,0x1F6075CE,0xF0AF20FF,0xA20A7141,0x41EB1D68,0x6DBC526C,0xB259FF37,0xFC82F4C0
.word 0x2A12004E,0xEAF9CA2F,0xCEFF02A1,0xB0BA4EFE,0xFBB45D3C,0x3294F931,0xFFBE4341,0x74113B2F
.word 0x0F906448,0xFF4301F0,0x0A33A14F,0x20AA3BFF,0xFA1A2E07,0x4EC0F0AC,0x643644E4,0x8F50FF46
.word 0x01F09740,0x7FF47FF4,0x80F0BEF2,0xF1FF8080,0xE03DF1F7,0xF19C5C4C,0xF2AEFBBB,0xFF952BBE
.word 0xE059BE42,0x3AF007F0,0x7FF17FF1,0xFEF07FF1,0xF0FEF0FF,0xF67FF507,0xF63FF63F,0x4BBFF03F
.word 0xFC23FF8B,0xFC43B780,0x01F07760,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x3AFA01F0,0x10F2C229,0xF001F0FF,0xF0FFFE01,0xBF01F001
.word 0x400E287D,0x50F6FF43,0xFAFA01F0,0x01F08BF3,0x377001F0,0xF6FF8420,0xF001F052,0xF0FFFA01
.word 0xAD01F001,0xFFBFF07E,0x01F001F0,0x1DF0FFF0,0x66F401F0,0x01F0C0F1,0x9E01F0FF,0xF1E14700
.word 0xF001F040,0x170D4A01,0x81F0FF77,0x01F001F0,0x01F001F1,0x41F001F0,0xF0FFDF87,0x9001F001
.word 0x491729FE,0xF021F0EF,0xFF7CB001,0x7F0D0B36,0xFFF2BE1F,0xBDF001F0,0xFE298122,0xF03FF0FF
.word 0x3A81FD01,0xF0673616,0xBF01F021,0x4FF6FF3F,0x01F001F0,0x862FC0C0,0x01F0BDF0,0xF2FF7FF4
.word 0xF001F0BE,0xF0FFF101,0xF001F080,0xFF3F2F01,0x811B8520,0x01F01FF0,0xCFF77CF0,0x01F001F0
.word 0xF07FF1FF,0xF001F01E,0xF0FEF001,0xF601F001,0x80F0FF3F,0x3FF001F0,0x01F0FCF3,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x07B066F1,0xE401F0EF,0xAF352B96,0x444C361E,0x174CD63E,0xF0528FFF,0x334F6A01,0x1E403D18
.word 0x44F60D8C,0x1F0AFFAF,0x818A31F0,0x7DC09444,0xB5347F7F,0xEAFF81F0,0x3E3E3E41,0xFE772B90
.word 0x3E01F03E,0xFFA43F3E,0x3C0F0301,0x7B507330,0x01F00780,0x533370B1,0x1DC43AEF,0x076333FD
.word 0x39F00750,0x0121BFAC,0xFC051EFF,0x2EBF4CBF,0x41E45CBA,0x06E72F55,0x6511FF53,0xB74F482F
.word 0x47513F81,0x01F07AF0,0xBCFF01F0,0x553F4F6A,0x7F0AFC00,0x4C123C46,0xFF7D501A,0x95AE5042
.word 0x7A51A9CE,0x875F9F5F,0x3FBC3FF1,0x0C4122FF,0x5CFD5176,0x210D123F,0x6039F08E,0xBD5CFFAC
.word 0x02339C17,0x962DE727,0x3BF0EC19,0x1CFF57DA,0x21BF22C4,0x278222A4,0x41FE226C,0xFF01F083
.word 0xA1801361,0x21FB2E53,0xBD9D01F0,0xCB12BFC3,0x3B8130FF,0x7881F072,0x3D3C8396,0x22E80ABD
.word 0x0421FF53,0xFFF072F9,0x2C53F892,0xC546C0F0,0x3FFFD961,0x5E0E36EA,0xF28A03BD,0xA980F0C0
.word 0xFF903956,0x10347DBE,0x851E6C39,0xBFF03EF0,0xFDC2BFF0,0x6E8637FF,0x147133D1,0x02312467
.word 0x34FE1E01,0x7330FFBB,0x0842A623,0xF96141FF,0x15437F25,0xF0FF243A,0x7FC0C003,0x258A2CC2
.word 0x179B5B40,0xFFA55766,0x01F00790,0x40F55768,0x01F040F5,0x0E3D4065,0x388340FF,0xA283F029
.word 0x14CB9BED,0x24E835D2,0x4025FFDC,0x77F0FFF1,0x3FB041C5,0xA8090845,0xF2FFEE3A,0xF001F08C
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0xF77B01F0,0x01F00FF1,0x945579E3,0x5E1DF0FF
.word 0x7E57F09D,0x441A323F,0xF1D66722,0x01F0FF99,0xAB268265,0x01F081FA,0x3EFE01F0,0xF0FF01F0
.word 0xF7C0BA01,0xF001F0CF,0x579FA501,0xFF01F0D7,0xBFFC01F0,0x01F0BFFC,0x677101F0,0x01F00EF3
.word 0xB801F0FF,0xF00BF3A1,0xF701F001,0xF001F0E7,0x40F0FF01,0x1CF0D757,0x3FFC01F0,0x5925EF34
.word 0xF0FF21F0,0x26FFE001,0xFF4109D7,0xF201F0BF,0xFF8F2900,0x3FF0BF42,0x61F301F0,0x67F3B929
.word 0x01F001F0,0x122A39FF,0xF041333D,0xE001F021,0x3B0E1581,0xBFF0FFEF,0xC0F001F0,0x01F02F68
.word 0xFCF101F0,0xF6FFD939,0xF001F053,0x477D4E01,0xF0BFF0A0,0xFFBFF001,0x01F0BFF0,0x00AF01F0
.word 0x7FF09F58,0x40F001F0,0xF0CFF7FF,0x7001F001,0xF0D767FF,0xF501F0FF,0x9E4CFF40,0x01F082F4
.word 0xCFF701F0,0x01F001F0,0x45FFBFC5,0xF0055301,0xF001F001,0xF0BEF03F,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0x4ABC4D01,0xD579FFD7
.word 0x871B2F5E,0x9F441D30,0x17300760,0x2DFFEE31,0x1ABC275C,0x87653DA6,0x44100B4C,0xFF1E75DB
.word 0x4050931B,0xFF7AFFFA,0x07F05EF6,0x153F5B1F,0x3F18577F,0xAB0CB130,0xE25C2A2E,0x17400780
.word 0xE52A33FF,0x1A417B2F,0x4E9132C1,0xF67DBB05,0xBFEDFFAF,0x3D2D0E29,0x3D2D050E,0x403B271C
.word 0xF2FF7DFC,0x15FB1CD9,0x3A6F4014,0xF000F1B9,0xFF767101,0xC12E1301,0x2639C83B,0x0340C13E
.word 0x85367EFD,0x410E36FF,0xF876FB2E,0xFB57F56F,0xF07EFB7E,0x3EFCFF37,0x6EF43EFC,0x0D4401F0
.word 0x821FC70F,0x3FFF6A70,0x52D13D00,0x40505171,0x7EA35ECF,0xFE0D53E6,0xC72DE539,0x3E702E41
.word 0x04583C58,0xFF07242F,0x8C223B1F,0x34402503,0xA905A825,0xBAF01730,0x212143FF,0x4D9E0328
.word 0x310441FF,0xF7AB27BD,0x97ABFF2F,0x3CF10E38,0x01F0FFFD,0xD043FB5B,0x6DFFE123,0x806746AB
.word 0x3FBEFDBE,0x4BBE3D6A,0xFFAE3063,0x8181BEF0,0x435C0559,0xB832D045,0xBEF0FAF3,0xF280F2FF
.word 0xF080F280,0x927E6301,0xCD7CF015,0x21F0FF1C,0x851F0F38,0xBEF01FF0,0x3FA487D4,0x11FFA52A
.word 0xF03FE4CE,0x42C2847E,0x24981824,0xFF0F50BE,0x79F07858,0xD535E551,0x22147D43,0x5C356D23
.word 0xF00F70FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0xBDF901F0,0x7F1F9717,0x01F0A767
.word 0x689401F0,0x198B44FF,0xF04EF37F,0xF381F001,0xF001F00D,0xBF9EFF01,0x021D4728,0x01F043F0
.word 0xB55BA7E7,0xF0FFC038,0xED54F091,0x3DF538FE,0xF001F083,0xFF6F9801,0x67F07267,0x3DF101F0
.word 0x7D21C534,0x01F041F0,0xFD3FF0FF,0xF001F07E,0xF17EFB01,0xF001F07D,0xCFF7FF01,0x01F001F0
.word 0xC7382688,0x1FF0FD21,0xF0FF01F0,0x53FE2001,0xF01EF00B,0x297DC201,0xFFEA26CA,0x01F07FFD
.word 0xD73741F0,0x41F1BD21,0xA9F501F0,0xF00393FF,0xDA01F01F,0x18D72928,0xF0A07BAE,0x01F0FF01
.word 0x213CBE90,0x01F0BEF0,0x70F301F0,0xF0FF01F0,0xF280F201,0xF001F080,0xF07CF001,0xFF01F001
.word 0x41F041F0,0x01F001F0,0x143A3452,0x01F0C2F2,0xDC3FF4FF,0x67418996,0x7099F0DF,0x50842A28
.word 0x546DFF7B,0x01F02AF0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF0FFF101,0x9DF7FE01
.word 0x3D000F0B,0x014DFFFF,0x48F0FFFD,0x80ABBF7A,0xC6DE6D4E,0xCBFFEFF2,0xEC724F02,0xFACC5CBC
.word 0x0A278FFF,0xFFE41CC3,0xF4DC411E,0x3FF0045D,0x344DCEA3,0x4F303F50,0x7FED24FF,0x6C01F02D
.word 0x0FBC1E35,0x2B4B2B69,0x6719FFB9,0x84E82B29,0x5F4181C0,0x8C5F720E,0x5DFF7FB1,0x797AF057
.word 0x4CD92915,0x2E411140,0xFF385C6D,0x01F0408C,0x15089458,0xF210C33D,0x3A6D2854,0x823FE0FF
.word 0x0FB53E44,0x5DFB6D31,0xE089CCF7,0x9450FFFC,0xDA54D927,0x03F0BE5C,0x858FBBF0,0x3DFFFC1D
.word 0x2A422241,0xF000F1E0,0x5E692F01,0xFF52F545,0x01F05AA3,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0xFFFDFFFD,0x01F001F0,0x4E805BFF,0xF040F0FE,0x20FAD601,0x38C82C79,0x01F0FF6D,0xE09801F0
.word 0x5526341B,0x01F03FFB,0x30FF64F8,0xF0CD48FD,0xDB01F07F,0x205726C1,0xFF6628FB,0x01F001F0
.word 0x3F4D3E91,0x01F08150,0x40FC01F0,0xFDD938FF,0xE001F0BF,0x39FD303E,0xF03FF095,0x3FF0FF01
.word 0x4422176A,0x01F001F0,0xCFF73DDD,0xF0FF01F0,0x37FF6E01,0xA10642DF,0x1ACF409A,0xFF01F046
.word 0x3E3F3D3F,0x9A89EF27,0x38F0CA52,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0x00019001
.section .rodata
.align 2
.global subErrorPal @ 512 unsigned chars
.hidden subErrorPal
subErrorPal:
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421
.hword 0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842
.hword 0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63
.hword 0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084
.hword 0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5
.hword 0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6
.hword 0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7
.hword 0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108
.hword 0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529
.hword 0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A
.hword 0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B
.hword 0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C
.hword 0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD
.hword 0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE
.hword 0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF
.hword 0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210
.hword 0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631
.hword 0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52
.hword 0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73
.hword 0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294
.hword 0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5
.hword 0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6
.hword 0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7
.hword 0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318
.hword 0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739
.hword 0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A
.hword 0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B
.hword 0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C
.hword 0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD
.hword 0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE
.hword 0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF
@}}BLOCK(subError)

View File

@ -1,29 +0,0 @@
//{{BLOCK(subLoad)
//======================================================================
//
// subLoad, 256x192@8,
// Transparent color : FF,00,FF
// + palette 256 entries, not compressed
// + 768 tiles lz77 compressed
// Total size: 512 + 5812 = 6324
//
// Time-stamp: 2023-11-03, 21:08:29
// Exported by Cearn's GBA Image Transmogrifier, v0.8.14
// ( http://www.coranac.com/projects/#grit )
//
//======================================================================
#ifndef GRIT_SUBLOAD_H
#define GRIT_SUBLOAD_H
#define subLoadTilesLen 5812
extern const unsigned int subLoadTiles[1453];
#define subLoadPalLen 512
extern const unsigned short subLoadPal[256];
#endif // GRIT_SUBLOAD_H
//}}BLOCK(subLoad)

View File

@ -1,269 +0,0 @@
@{{BLOCK(subLoad)
@=======================================================================
@
@ subLoad, 256x192@8,
@ Transparent color : FF,00,FF
@ + palette 256 entries, not compressed
@ + 768 tiles lz77 compressed
@ Total size: 512 + 5812 = 6324
@
@ Time-stamp: 2023-11-03, 21:08:29
@ Exported by Cearn's GBA Image Transmogrifier, v0.8.14
@ ( http://www.coranac.com/projects/#grit )
@
@=======================================================================
.section .rodata
.align 2
.global subLoadTiles @ 5812 unsigned chars
.hidden subLoadTiles
subLoadTiles:
.word 0x00C00010,0xF0FFFF3F,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xF801F001,0x01F001F0,0x01F001F0,0x00000170
.section .rodata
.align 2
.global subLoadPal @ 512 unsigned chars
.hidden subLoadPal
subLoadPal:
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421
.hword 0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842
.hword 0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63
.hword 0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084
.hword 0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5
.hword 0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6
.hword 0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7
.hword 0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108
.hword 0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529
.hword 0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A
.hword 0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B
.hword 0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C
.hword 0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD
.hword 0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE
.hword 0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF
.hword 0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210
.hword 0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631
.hword 0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52
.hword 0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73
.hword 0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294
.hword 0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5
.hword 0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6
.hword 0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7
.hword 0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318
.hword 0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739
.hword 0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A
.hword 0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B
.hword 0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C
.hword 0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD
.hword 0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE
.hword 0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF
@}}BLOCK(subLoad)

View File

@ -1,29 +0,0 @@
//{{BLOCK(subPrompt)
//======================================================================
//
// subPrompt, 256x192@8,
// Transparent color : FF,00,FF
// + palette 256 entries, not compressed
// + 768 tiles lz77 compressed
// Total size: 512 + 7196 = 7708
//
// Time-stamp: 2023-11-03, 21:08:29
// Exported by Cearn's GBA Image Transmogrifier, v0.8.14
// ( http://www.coranac.com/projects/#grit )
//
//======================================================================
#ifndef GRIT_SUBPROMPT_H
#define GRIT_SUBPROMPT_H
#define subPromptTilesLen 7196
extern const unsigned int subPromptTiles[1799];
#define subPromptPalLen 512
extern const unsigned short subPromptPal[256];
#endif // GRIT_SUBPROMPT_H
//}}BLOCK(subPrompt)

View File

@ -1,318 +0,0 @@
@{{BLOCK(subPrompt)
@=======================================================================
@
@ subPrompt, 256x192@8,
@ Transparent color : FF,00,FF
@ + palette 256 entries, not compressed
@ + 768 tiles lz77 compressed
@ Total size: 512 + 7196 = 7708
@
@ Time-stamp: 2023-11-03, 21:08:29
@ Exported by Cearn's GBA Image Transmogrifier, v0.8.14
@ ( http://www.coranac.com/projects/#grit )
@
@=======================================================================
.section .rodata
.align 2
.global subPromptTiles @ 7196 unsigned chars
.hidden subPromptTiles
subPromptTiles:
.word 0x00C00010,0xF0FFFF3F,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0E301,0x078001F0,0xF0F4F4FA
.word 0x8101F015,0xFFFF01F0,0xF9F4F4F4,0xF0EF15F0,0x8001F001,0x15F0F57C,0x01F001F0,0xF0F7BFF0
.word 0xE001F001,0xFC0210BF,0x01F019F0,0x30BC01F0,0x0401FC0B,0x01F015F0,0xFFFF01F0,0xF0FAF0F0
.word 0x9001F001,0x9CB5E006,0xF0E77FB3,0xF001F017,0xF03E7101,0xF001F0BF,0x3F61FB01,0x01F03EF1
.word 0x087001F0,0xF07FF0FB,0x01F0FE01,0xFFF17F22,0x01F001F0,0xBD12BF62,0x3FF0FFFD,0x01F001F0
.word 0x8441FF22,0x01F019F0,0xFF3F01F0,0xF0BCF1FF,0xC101F001,0xF0BFF1BC,0x01F0DE01,0xF1FCBF53
.word 0xF001F03F,0xF7FF6301,0xF015F0F7,0x4001F001,0xBFF0F70B,0x01F001F0,0xFEBF93BF,0x01F016F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0F8,0xF001F001,0xFF01F001,0x013994FF,0xF007F001
.word 0x0107F007,0x04010001,0xF6762A04,0x010920FF,0x0EF5042B,0x001F4649,0x84317915,0x015BDE06
.word 0x07002801,0x00C0B9FF,0x99071023,0x25120101,0x93BE02C0,0x41010113,0x59012F30,0x195420C0
.word 0x07F05C40,0x17F0FAFF,0xF007C0FD,0xF007F097,0x10BF8007,0x0750B4C4,0x4D4D0B13,0x25CA0110
.word 0x07502541,0x79791115,0x40CA0100,0x07609CE7,0x814C11B5,0x54110601,0xD507302C,0x01841511
.word 0x01018064,0x2B77104F,0xB1010001,0xD4FFFF28,0x05000101,0xFFFF6EF0,0x0001017F,0xFFBDFF46
.word 0x010129FF,0xF0F49004,0x8E31EF07,0x2188A001,0x4C01F696,0x01979E21,0x11F04207,0x010164A7
.word 0x71AF11A1,0x4D010113,0x01BEB711,0x43011840,0xC811A24B,0x822152E1,0x41640057,0x8F120552
.word 0x010777AE,0xE7016C98,0x014CA201,0xFAA31301,0x10845F10,0xFFBE6219,0x35A83183,0x5CCE1CFF
.word 0x10BD110A,0x37C61165,0xCE3193FD,0x2621DD19,0x2E31EA0B,0x80930621,0x41DC1107,0xA1EE17F6
.word 0x3FFF413E,0x3E41FFB4,0x3E4163E2,0x36012732,0x02BC3E81,0x9F31A88F,0x07F007F0,0x010107C0
.word 0x220206F9,0xF007F087,0x0107F007,0x8A0E0332,0x01019A01,0x3A0740B5,0x1015AA21,0x11BD0101
.word 0x010159B2,0xBA118043,0x0101108D,0x0001DAC6,0x01608201,0x01E54C01,0xBF700101,0xD6030101
.word 0x41DB1001,0xF6071084,0x0F10E901,0x10E70297,0xBC01B717,0x011F106C,0x271013BC,0x2F30BC01
.word 0x208401FF,0x21840137,0x23EA01BC,0x21840149,0x8411FEBC,0x8401BC11,0x1F12BC21,0xC741BC11
.word 0x8401FF35,0x8481BC21,0xC3120790,0xBC01BCF1,0xD0FDC302,0x33BC212F,0x210720C7,0x0127F3BC
.word 0x23E0BC21,0xA0F302EF,0x1E010107,0x4381E15D,0x0EDB0EFF,0x041E4C4D,0x2D4A3B15,0x1000F311
.word 0x04B10710,0x000F0026,0x010147EB,0x0809011A,0x7E3414A0,0x6B053924,0xDC49FFFC,0x0750BF40
.word 0x0480037F,0x059B2756,0xF6013D01,0xB4240740,0x802407F0,0xABDF42E4,0x03310710,0xE104ECBF
.word 0xF0E544A4,0x07B0FF07,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF3FFF701,0x8007F0EF,0x80418007,0x9B0F0128,0x818113FF,0x06B17E89,0xD737D734,0xF701F047
.word 0x010F60D7,0x5E05117E,0x07706438,0xA7F001F0,0x58113910,0x219F482F,0x3DD00790,0xA2D8D81F
.word 0xE0F00100,0x45450AAF,0xEB840110,0x0606A748,0xE058EB28,0x7F45D37D,0x0102D134,0x010128FF
.word 0xD2430834,0xE31A09A1,0x017DAA00,0xB1103C01,0x0101270F,0x27B9F091,0x09D82797,0xF1178849
.word 0x170E4DF9,0xFF2FE9D8,0x01016300,0x28FCFF4E,0x01B600FF,0xFFF10801,0xF906FFC4,0xA3010111
.word 0x0F003FF0,0x209D03F2,0x927C0101,0x7A05131D,0x7B170F61,0x07016905,0xBC068761,0x294E00C9
.word 0x1945CEA4,0x086003AB,0xA8BC1A31,0x48DD17C5,0x3E218377,0x5401251F,0x6501EF37,0x21970740
.word 0x320A3756,0xE619E70E,0xD0EE49E5,0xEF3E417F,0x3E415EEE,0x6059174A,0xF7BEF007,0xFC07F0D7
.word 0x7F9207D0,0x07F0D7F7,0x7CD00770,0x3805FF5D,0x0F860101,0x0AB26B01,0x092E4DAD,0x082EFE65
.word 0xA66D19E6,0x0995DD1A,0x4124FC75,0xFFF09AA4,0xB3C737FF,0x01F90730,0xE90F0884,0x0884012F
.word 0x02FC5717,0x1F18070A,0x28D301C4,0xBE840127,0xA1E1FC40,0x218411BC,0x218401BC,0xFF7F65BC
.word 0x8401BC21,0x8401612B,0x8401BC21,0x42FFBCA1,0xF7C312FB,0x02BC01EF,0xE11FE8C3,0xB6670ABF
.word 0x21013FF3,0x59DF3BBC,0xBCD10790,0x07694014,0xFFF419AD,0x0AF7FF31,0x7F010117,0x03FF0700
.word 0xE5410B33,0x0CEDFF0B,0x1B620101,0x09706FFF,0xE0071C2A,0x02D0BF57,0x0F60D7F7,0x0748D05F
.word 0x801F9044,0xF0D7F742,0xFFEFF707,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FE01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xE8FF12FF,0xDC1410AF,0xCAD7244F,0x082B0FC8,0x051FF1C7,0xFFFF2601,0x08058855,0x32D5065E
.word 0xE0F3C40E,0xAF9A123B,0x3AD758D9,0x09374FCF,0xFFFFC805,0x710F666A,0x166A1077,0x2C6E37ED
.word 0xF5F6FF9C,0x0BFC0C20,0xF5F4F4F4,0x17811600,0x44DD0FD2,0xA078152C,0x7F25D5FF,0x8012FF4C
.word 0x96000101,0xB00FFF07,0x2B08E7B1,0x0F003FF0,0x9C0EF4FA,0x0F10D7F8,0x007420DD,0x8FF9A117
.word 0x7C004820,0xEF275EF7,0x97FD97FD,0x00F77DE0,0xFDC100BE,0xCF97FD97,0x7F208FF5,0xBF00FEF4
.word 0x73468F2D,0x2DFF0710,0x25CF0097,0xF0078097,0xF0BFF03F,0xBDBFF0BF,0x10FB0770,0x283328BD
.word 0xFE07C003,0xF6751740,0x7BF11F60,0x47FCC001,0x5F9F032F,0x3E41080B,0x1D931119,0x07209B41
.word 0x2001F0CD,0x0F69210D,0x073F22A4,0x19A4AA21,0x8402B97C,0x660816B6,0x8944FFFD,0xFFC09E20
.word 0xFF3AF032,0x9AAC02E2,0xD7FFD8B0,0x1801C319,0x4F10C801,0x51BE0763,0x335E8B90,0x1299C507
.word 0xF0564A64,0x303F4201,0x424BBE4A,0xA74FAB03,0x5C4F2256,0x22F85127,0xF1FBF657,0x10BF517F
.word 0xF74AADFF,0x0B0750B4,0x0102FE01,0xFFCFFBCA,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0x227FEF01,0x2E1D03F8,0x0CE4FFFF
.word 0x00AB88DF,0xE70CE61E,0x048C1D85,0x2E107D0C,0x0101370A,0x90AA1713,0xB755000D,0x1DF49807
.word 0xD1C215CE,0x3FF6B00C,0x10C0DDCF,0x7EC40759,0x39EAFFFF,0xFFF00536,0x0F595B28,0xDD1F56A0
.word 0x0C010100,0xD4017DCA,0x05010801,0xF90C6EF0,0x00460101,0x0101BDFF,0x90010129,0x18F0F436
.word 0x3402D071,0xDD0F4115,0x6610ADE3,0xB6BE4563,0xE717571E,0xBF4D1807,0x45A2A31D,0x1D701EB7
.word 0x2D1810B3,0xA61800BB,0x4E4EC32D,0x18F108D7,0xEB0F071F,0x1AED0F85,0x1D080901,0xE52D7EE0
.word 0xFC6B051F,0x97FD97FD,0x77FD971D,0xF0FF07F0,0xD7977D07,0xF007F0CF,0xF0FF9707,0xFBBFF0BF
.word 0xBF90BFF0,0x07F0E7F7,0x57D007F0,0xD0CFD7FF,0xEF9707F0,0x069319FE,0x82103335,0x01144F7F
.word 0x01F88401,0x01083A47,0x09E46B01,0x010139AF,0x01E66C04,0x2F0AFEFF,0x0410F985,0x770FA2FF
.word 0xAD36FFC1,0x01011201,0x8EFFFD27,0xB80AC71F,0x0AF3FFFF,0x1F38A01B,0xEF09808E,0x0101F8F8
.word 0x50FFFFB0,0xACA31F41,0xFF890740,0x19B87AFF,0x72293372,0x2800BD0F,0x8123FEFF,0x9652C60F
.word 0x18D1458E,0xF81ACF3F,0x9320F8F8,0x90D8DD0F,0x40AE1907,0x1740550F,0x081FC042,0x11CB204D
.word 0x0079792A,0x6749CA01,0x1F07609C,0x00D8D82C,0xE767F001,0x450AF757,0x01104577,0xFF208B01
.word 0xF033F359,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FC01F0
.word 0xF001F001,0xF001F001,0xE10D1001,0x47054F58,0xF0BAEFC7,0x9001F01D,0x00C50505,0x27FFD846
.word 0xE4B9A601,0xF01CF0EB,0x913FF001,0xF0F91420,0x8101F01A,0xFFFF01F0,0xA3010111,0xF0F787FD
.word 0x3001F001,0xE0C7170B,0x01F087FF,0x20BF01F0,0xC7FF440C,0x01F001F0,0xC7FF0860,0xF0FF01F0
.word 0xF0BFF001,0xF001F019,0xFFBF1001,0xEE01F0C7,0x086001F0,0xF00AC737,0xF001F018,0xFF0FFF01
.word 0xF0DE6E27,0xF001F014,0x10095001,0x38075FE3,0xBFF4FF47,0xC9AE38A7,0x01F020F0,0x82140590
.word 0xCF2FBFFA,0xF01AF0FC,0x4701F001,0xF0C7F7EF,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0C001,0x00000110
.section .rodata
.align 2
.global subPromptPal @ 512 unsigned chars
.hidden subPromptPal
subPromptPal:
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421
.hword 0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842
.hword 0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63
.hword 0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084
.hword 0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5
.hword 0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6
.hword 0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7
.hword 0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108
.hword 0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529
.hword 0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A
.hword 0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B
.hword 0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C
.hword 0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD
.hword 0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE
.hword 0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF
.hword 0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210
.hword 0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631
.hword 0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52
.hword 0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73
.hword 0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294
.hword 0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5
.hword 0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6
.hword 0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7
.hword 0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318
.hword 0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739
.hword 0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A
.hword 0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B
.hword 0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C
.hword 0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD
.hword 0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE
.hword 0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF
@}}BLOCK(subPrompt)

View File

@ -1,29 +0,0 @@
//{{BLOCK(topError)
//======================================================================
//
// topError, 256x192@8,
// Transparent color : FF,00,FF
// + palette 256 entries, not compressed
// + 768 tiles lz77 compressed
// Total size: 512 + 6340 = 6852
//
// Time-stamp: 2023-11-03, 21:08:28
// Exported by Cearn's GBA Image Transmogrifier, v0.8.14
// ( http://www.coranac.com/projects/#grit )
//
//======================================================================
#ifndef GRIT_TOPERROR_H
#define GRIT_TOPERROR_H
#define topErrorTilesLen 6340
extern const unsigned int topErrorTiles[1585];
#define topErrorPalLen 512
extern const unsigned short topErrorPal[256];
#endif // GRIT_TOPERROR_H
//}}BLOCK(topError)

View File

@ -1,288 +0,0 @@
@{{BLOCK(topError)
@=======================================================================
@
@ topError, 256x192@8,
@ Transparent color : FF,00,FF
@ + palette 256 entries, not compressed
@ + 768 tiles lz77 compressed
@ Total size: 512 + 6340 = 6852
@
@ Time-stamp: 2023-11-03, 21:08:28
@ Exported by Cearn's GBA Image Transmogrifier, v0.8.14
@ ( http://www.coranac.com/projects/#grit )
@
@=======================================================================
.section .rodata
.align 2
.global topErrorTiles @ 6340 unsigned chars
.hidden topErrorTiles
topErrorTiles:
.word 0x00C00010,0xF0FFFF3F,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0E201,0x01D001F0,0x00F4F4FA,0xFF0CFF01
.word 0x00010194,0x0907A001,0x204C584C,0x35101D17,0xF81C0780,0x2F50CAF8,0xFFFF3B30,0x90093C00
.word 0x4C154C07,0x6B00514C,0x806F40D5,0xFE007730,0xF8F8F82B,0x40FFFFFE,0xD06B10D4,0x017FFFFF
.word 0x7D00A8FC,0x819400F5,0xEF077D00,0x2CFF28FF,0x20A08510,0x4B01014F,0x4E5710A8,0x00F01800
.word 0x0128B15F,0xFFA10100,0x6EF00501,0x4C010101,0xFF4501FF,0x2D1820BD,0xBF40F7FF,0x50BF4048
.word 0x82007F07,0x10CF10DF,0x07F005F1,0xFC200F40,0xFC209100,0x0780E455,0xECC10031,0x31A4D700
.word 0x07F0D731,0x41FB4971,0x3F21A803,0x07F007F0,0x010770EB,0xF980110C,0x51328041,0x5207B088
.word 0x590F4015,0x108D1740,0x5882B031,0xFDCF0160,0x5431BE11,0x92B5FF11,0xFE3A0740,0xBD010F30
.word 0x89420740,0xC6010F40,0x4B0730DA,0xFF2F10E5,0x9201BD30,0xCA119D20,0x07F007F0,0x7D310770
.word 0x31F4F426,0x5001017D,0x017D3107,0x75313173,0x07F03D31,0x7C40A401,0x01FF3F12,0x3107707D
.word 0xF001F07D,0xF2BFF201,0xFFBFF2BF,0xBFF2BFF2,0xBFF2BFF2,0xBFF2BFF2,0xBF92BFF2,0xF080F1FE
.word 0x7007F007,0x10FF0007,0x19FF1080,0xF007F0FF,0x3107D007,0x01572142,0xF007F042,0x0790D507
.word 0x41FCFE41,0x0750B4FE,0x9840010B,0x25CA4301,0x0750B041,0xA5797911,0x31CA0100,0x519C011F
.word 0xBE41FCBE,0xC6410350,0x08CE1101,0xE2193E41,0x07C0BEF1,0x69211042,0x019F33DC,0x41A10724
.word 0x02B903CF,0x0A16B62C,0xFD280101,0x11C07C43,0x011014C2,0x45128401,0x6B01013A,0xF04DF2FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0F101,0x01D001F0,0x5D0B3785,0xE060F35D
.word 0x789307F0,0x29FE0725,0x0A5D5D01,0xD3FFE15D,0x377E6F47,0x04D0FE77,0xD26F10F1,0x017DF746
.word 0x15843C01,0x01012744,0x903F6091,0x13F007F4,0x46A20101,0x1533163E,0x340721C7,0x010E3F14
.word 0xB010E301,0xC7476353,0xF9CF47B6,0x50CF4711,0xD777EACD,0xE7175015,0x4DEF47A2,0x5F08F747
.word 0xA38146F1,0xCFF70798,0x07F007F0,0xF7F901D0,0xF007F0D7,0x36473007,0x36BF70B8,0xFE5D2BC0
.word 0x404DC836,0x07F04C17,0x71900F40,0x17D6037F,0x010138F7,0x070F5486,0xEE04B2FF,0xFE07082E
.word 0x0D08D92E,0x17A6DF17,0xFCE70716,0x3F073024,0x07409AFF,0x56F6BD90,0x07D007F0,0xF7FF7D91
.word 0xF007F0D7,0xF001F007,0xF201F001,0xFFBFF2BF,0x07F0AFF2,0xBFF2BFF2,0xBFF2BFF2,0xBFF2BFF2
.word 0xF1BFF2FF,0x0A683180,0x027021D0,0x027821BF,0x8021FEBF,0x8821BF02,0x80C1BF02,0x07E0D7F7
.word 0x09117C01,0xB11FD9E8,0x3907F042,0x2E111132,0x5A492F11,0x81079021,0x1FC7273F,0x00D8D82C
.word 0xE767F001,0x440AF757,0x01104457,0x591E4A84,0xBE910750,0x69A19EF1,0xD619FEAE,0x10333506
.word 0x09A11798,0x07720AE8,0x6C010139,0x01B09A19,0x1D028585,0xFFC18911,0x120DADFF,0x07270101
.word 0xB85318F7,0x09831738,0x27FFFF95,0x42F2DE6E,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0x8001F001
.word 0x00000001
.section .rodata
.align 2
.global topErrorPal @ 512 unsigned chars
.hidden topErrorPal
topErrorPal:
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421
.hword 0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842
.hword 0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63
.hword 0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084
.hword 0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5
.hword 0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6
.hword 0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7
.hword 0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108
.hword 0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529
.hword 0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A
.hword 0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B
.hword 0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C
.hword 0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD
.hword 0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE
.hword 0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF
.hword 0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210
.hword 0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631
.hword 0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52
.hword 0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73
.hword 0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294
.hword 0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5
.hword 0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6
.hword 0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7
.hword 0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318
.hword 0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739
.hword 0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A
.hword 0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B
.hword 0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C
.hword 0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD
.hword 0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE
.hword 0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF
@}}BLOCK(topError)

View File

@ -1,29 +0,0 @@
//{{BLOCK(topLoad)
//======================================================================
//
// topLoad, 256x192@8,
// Transparent color : FF,00,FF
// + palette 256 entries, not compressed
// + 768 tiles lz77 compressed
// Total size: 512 + 5860 = 6372
//
// Time-stamp: 2023-11-03, 21:08:29
// Exported by Cearn's GBA Image Transmogrifier, v0.8.14
// ( http://www.coranac.com/projects/#grit )
//
//======================================================================
#ifndef GRIT_TOPLOAD_H
#define GRIT_TOPLOAD_H
#define topLoadTilesLen 5860
extern const unsigned int topLoadTiles[1465];
#define topLoadPalLen 512
extern const unsigned short topLoadPal[256];
#endif // GRIT_TOPLOAD_H
//}}BLOCK(topLoad)

View File

@ -1,271 +0,0 @@
@{{BLOCK(topLoad)
@=======================================================================
@
@ topLoad, 256x192@8,
@ Transparent color : FF,00,FF
@ + palette 256 entries, not compressed
@ + 768 tiles lz77 compressed
@ Total size: 512 + 5860 = 6372
@
@ Time-stamp: 2023-11-03, 21:08:29
@ Exported by Cearn's GBA Image Transmogrifier, v0.8.14
@ ( http://www.coranac.com/projects/#grit )
@
@=======================================================================
.section .rodata
.align 2
.global topLoadTiles @ 5860 unsigned chars
.hidden topLoadTiles
topLoadTiles:
.word 0x00C00010,0xF0FFFF3F,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FC01,0x01F001F0,0x01F001F0,0x070701E0,0x15F0077F,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF101F001,0x01F0FF03,0x3CF001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xE601F001
.word 0x07F0FE86,0x07F007F0,0x192001F0,0x06201B10,0x2740FF07,0x0F5007F0,0x5C703FF0,0x6E004970
.word 0xF0FF07F0,0x409EA082,0xF08C305F,0xC00F5007,0xFFB34034,0xD1700270,0x85F007F0,0x07F05FF0
.word 0xBFA07FE0,0xF0BA30FF,0xF107F07F,0x81FAA000,0xF0B8F13D,0x0EF2FF3C,0x07F007F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x07F0F0F5,0x4E9607F0,0xF707D0FF,0x7707F0D7,0x56D5B6EF,0x96DF9646
.word 0x07E0FFB9,0xAF67DB77,0x5FF79590,0x9C6807B0,0xF7FFA050,0xC007F057,0x779967B1,0xF007F0FF
.word 0xFF07F007,0x67F03D61,0x07F007F0,0x07F07FB8,0x3671B8B1,0xF0F891FF,0x5707F02D,0xF803F0EF
.word 0x7201F003,0x03F0FF66,0x01F03FF0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x69FF01F0,0xF01DB8C0,0x8901F001,0xF0064AFE,0xFF01F01A,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001
.word 0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001
.word 0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001
.word 0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF
.word 0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0
.word 0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0
.word 0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0
.word 0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01,0x01F001F0
.word 0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001,0x01F001F0
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001,0x01F0FF01
.word 0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001,0xFF01F001
.word 0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001,0xF001F001
.word 0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FF01F0,0xF001F001,0xF001F001,0xF001F001
.word 0xFF01F001,0x01F001F0,0x01F001F0,0x01F001F0,0x01F001F0,0xF001F0FF,0xF001F001,0xF001F001
.word 0xF001F001,0x01F0FF01,0x01F001F0,0x01F001F0,0x01F001F0,0xF0FC01F0,0xF001F001,0xF001F001
.word 0x00016001
.section .rodata
.align 2
.global topLoadPal @ 512 unsigned chars
.hidden topLoadPal
topLoadPal:
.hword 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
.hword 0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421,0x0421
.hword 0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842
.hword 0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63
.hword 0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084
.hword 0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5
.hword 0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6
.hword 0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7
.hword 0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108,0x2108
.hword 0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529,0x2529
.hword 0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A,0x294A
.hword 0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B,0x2D6B
.hword 0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C,0x318C
.hword 0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD,0x35AD
.hword 0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE,0x39CE
.hword 0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF,0x3DEF
.hword 0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210,0x4210
.hword 0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631,0x4631
.hword 0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52,0x4A52
.hword 0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73,0x4E73
.hword 0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294,0x5294
.hword 0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5,0x56B5
.hword 0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6,0x5AD6
.hword 0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7,0x5EF7
.hword 0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318
.hword 0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739,0x6739
.hword 0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A,0x6B5A
.hword 0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B,0x6F7B
.hword 0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C,0x739C
.hword 0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD,0x77BD
.hword 0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE,0x7BDE
.hword 0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7FFF
@}}BLOCK(topLoad)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

View File

@ -32,7 +32,6 @@
// #include "nds_card.h"
#include "topLoad.h"
#include "subLoad.h"
#include "topError.h"
#include "subError.h"
#include "subPrompt.h"
@ -40,6 +39,8 @@
#define CONSOLE_SCREEN_WIDTH 32
#define CONSOLE_SCREEN_HEIGHT 24
static bool ScreenInit = false;
void vramcpy_ui (void* dest, const void* src, int size)
{
u16* destination = (u16*)dest;
@ -51,6 +52,7 @@ void vramcpy_ui (void* dest, const void* src, int size)
}
void BootSplashInit() {
if (ScreenInit)return;
videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);
videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
vramSetBankA (VRAM_A_MAIN_BG_0x06000000);
@ -61,50 +63,25 @@ void BootSplashInit() {
BG_PALETTE[255]=0xffff;
u16* bgMapTop = (u16*)SCREEN_BASE_BLOCK(0);
u16* bgMapSub = (u16*)SCREEN_BASE_BLOCK_SUB(0);
for (int i = 0; i < CONSOLE_SCREEN_WIDTH*CONSOLE_SCREEN_HEIGHT; i++) {
bgMapTop[i] = (u16)i;
bgMapSub[i] = (u16)i;
}
}
void LoadScreen() {
// Display Load Screen
decompress((void*)topLoadTiles, (void*)CHAR_BASE_BLOCK(2), LZ77Vram);
decompress((void*)subLoadTiles, (void*)CHAR_BASE_BLOCK_SUB(2), LZ77Vram);
vramcpy_ui (&BG_PALETTE[0], topLoadPal, topLoadPalLen);
vramcpy_ui (&BG_PALETTE_SUB[0], subLoadPal, subLoadPalLen);
for (int i = 0; i < CONSOLE_SCREEN_WIDTH*CONSOLE_SCREEN_HEIGHT; i++) { bgMapTop[i] = (u16)i; bgMapSub[i] = (u16)i; }
ScreenInit = true;
}
void CartridgePrompt() {
BootSplashInit();
// Display Load Screen
decompress((void*)topLoadTiles, (void*)CHAR_BASE_BLOCK(2), LZ77Vram);
decompress((void*)subPromptTiles, (void*)CHAR_BASE_BLOCK_SUB(2), LZ77Vram);
vramcpy_ui (&BG_PALETTE[0], topLoadPal, topLoadPalLen);
vramcpy_ui (&BG_PALETTE_SUB[0], subPromptPal, subPromptPalLen);
for (int i = 0; i < 20; i++) { swiWaitForVBlank(); }
}
int main( int argc, char **argv) {
defaultExceptionHandler();
// u32 ndsHeader[0x80];
// char gameid[4];
BootSplashInit();
if (fatInitDefault()) {
CIniFile GM9NBootstrap( "/_nds/GM9N_Bootstrap.ini" );
CIniFile GM9NBootstrap( "/_nds/GM9N_Bootstrap.ini" );
std::string ndsPath = GM9NBootstrap.GetString( "GM9N_BOOTSTRAP", "SRL", "/NDS/GodMode9Nrio.nds");
LoadScreen();
if (REG_SCFG_MC == 0x11) {
do { CartridgePrompt(); }
while (REG_SCFG_MC == 0x11);
@ -118,9 +95,9 @@ int main( int argc, char **argv) {
enableSlot1();
}
}
runNdsFile(ndsPath.c_str(), 0, NULL);
} else {
BootSplashInit();
// Display Error Screen
decompress((void*)topErrorTiles, (void*)CHAR_BASE_BLOCK(2), LZ77Vram);
decompress((void*)subErrorTiles, (void*)CHAR_BASE_BLOCK_SUB(2), LZ77Vram);

View File

@ -117,7 +117,7 @@ void __attribute__ ((long_call)) __attribute__((noreturn)) __attribute__((naked)
#ifdef NTRMODE
// REG_SCFG_CLK = 0x80;
REG_SCFG_EXT = 0x83000000;
REG_SCFG_EXT = 0x03000000;
#endif
arm9code();
while(1);

Binary file not shown.