init commit take 2

This commit is contained in:
Reisyukaku 2015-08-04 21:57:37 -04:00
commit e2b7f1e607
90 changed files with 16818 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build.bat
data/firmware.bin

84
Makefile Normal file
View File

@ -0,0 +1,84 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
OPENSSL := openssl
PYTHON3 := python
PYTHON_VER_MAJOR := $(word 2, $(subst ., , $(shell python --version 2>&1)))
ifneq ($(PYTHON_VER_MAJOR), 3)
PYTHON3 := py -3
endif
dir_source := source
dir_data := data
dir_build := build
dir_mset := mset
dir_out := out
dir_emu := emunand
dir_thread := thread
ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
CFLAGS := -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main
FLAGS := dir_out=$(abspath $(dir_out))
objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))
.PHONY: all
all: launcher
.PHONY: launcher
launcher: $(dir_out)/ReiNand.dat
.PHONY: clean
clean:
@$(MAKE) $(FLAGS) -C $(dir_mset) clean
rm -rf $(dir_out) $(dir_build)
.PHONY: $(dir_out)/ReiNand.dat
$(dir_out)/ReiNand.dat: $(dir_build)/main.bin $(dir_out)/rei/ $(dir_out)/rei/thread/arm9.bin $(dir_out)/rei/emunand/emunand.bin
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher
dd if=$(dir_build)/main.bin of=$@ bs=512 seek=256
$(dir_out)/rei/: $(dir_data)/firmware.bin $(dir_data)/splash.bin
@mkdir -p "$(dir_out)/rei"
@cp -av $(dir_data)/*bin $@
$(dir_out)/rei/thread/arm9.bin: $(dir_thread)
@$(MAKE) -C $(dir_thread)
@mkdir -p "$(dir_out)/rei/thread"
@mv $(dir_thread)/arm9.bin $(dir_out)/rei/thread
$(dir_out)/rei/emunand/emunand.bin: $(dir_emu)/emuCode.s
@armips $<
@mkdir -p "$(dir_out)/rei/emunand"
@mv emunand.bin $(dir_out)/rei/emunand
$(dir_build)/main.bin: $(dir_build)/main.elf
$(OC) -S -O binary $< $@
$(dir_build)/main.elf: $(objects_cfw)
# FatFs requires libgcc for __aeabi_uidiv
$(CC) -nostartfiles $(LDFLAGS) -T linker.ld $(OUTPUT_OPTION) $^
$(dir_build)/%.o: $(dir_source)/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(dir_build)/%.o: $(dir_source)/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
$(dir_build)/fatfs/%.o: $(dir_source)/fatfs/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) -mthumb -mthumb-interwork -Wno-unused-function $(OUTPUT_OPTION) $<
$(dir_build)/fatfs/%.o: $(dir_source)/fatfs/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) -mthumb -mthumb-interwork $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

BIN
data/splash.bin Normal file

Binary file not shown.

155
emunand/emuCode.s Normal file
View File

@ -0,0 +1,155 @@
.nds
sdmmc equ 0x80D86F0
sdmmc_unk1 equ 0x080788C0
aes_unk equ 0x0805F9E4
aes_setkey equ 0x08057458
sdmmc_unk2 equ 0x080786A0
sdmmc_unk0 equ 0x08062890
.create "emunand.bin", 0x0801A4C0
.org 0x0801A4C0
.arm
patch000_00:
stmfd sp!, {r0-r3}
mov r3, r0
ldr r1, =orig_sector
ldr r2, [r3,#4]
str r2, [r1,#4]
ldr r0, =sdmmc
cmp r2, r0
ldr r2, [r3,#8]
str r2, [r1]
beq @@orig_code
ldr r1, =sdmmc
str r1, [r3,#4]
cmp r2, #0
ldr r0, =nand_offset
ldrne r0, [r0]
addne r0, r2
ldreq r0, [r0, #(ncsd_header_offset - nand_offset)]
str r0, [r3,#8]
@@orig_code:
ldmfd sp!, {r0-r3}
movs r4, r0
movs r5, r1
movs r7, r2
movs r6, r3
movs r0, r1, lsl#23
beq loc_801a534
stmfd sp!, {r4}
ldr r4, =(sdmmc_unk0 + 1)
blx r4
ldmfd sp!, {r4}
loc_801a534:
ldr r0, [r4,#4]
ldr r1, [r0]
ldr r1, [r1,#0x18]
blx r1
ldr r1, [r4,#4]
movs r3, r0
ldr r0, [r1,#0x20]
movs r2, r5, lsr#9
mov r12, r0
ldr r0, [r4,#8]
str r7, [sp,#4]
adds r0, r0, r2
cmp r1, #0
str r6, [sp,#8]
str r0, [sp]
beq loc_801a578
adds r1, r1, #8
loc_801a578:
movs r2, r4
adds r2, r2, #0xc
mov r0, r12
ldr r5, =(sdmmc_unk1 + 1) ; called by the original function
blx r5
stmfd sp!, {r0-r3}
ldr r2, =orig_sector
ldr r1, [r2]
str r1, [r4,#8]
ldr r1, [r2,#4]
str r1, [r4,#4]
ldmfd sp!, {r0-r3}
ldmfd sp!, {r1-r7,lr}
bx lr
patch000_01:
stmfd sp!, {r0-r3}
mov r3, r0
ldr r1, =orig_sector
ldr r2, [r3,#4]
str r2, [r1,#4]
ldr r0, =sdmmc
cmp r2, r0
ldr r2, [r3,#8]
str r2, [r1]
beq @@orig_code
ldr r1, =sdmmc
str r1, [r3,#4]
cmp r2, #0
ldr r0, =nand_offset
ldrne r0, [r0]
addne r0, r2
ldreq r0, [r0, #(ncsd_header_offset - nand_offset)]
str r0, [r3,#8]
@@orig_code:
ldmfd sp!, {r0-r3}
movs r4, r0
movs r5, r1
movs r7, r2
movs r6, r3
movs r0, r1, lsl#23
beq loc_801a624
stmfd sp!, {r4}
ldr r4, =(sdmmc_unk0 + 1)
blx r4
ldmfd sp!, {r4}
loc_801a624:
ldr r0, [r4,#4]
ldr r1, [r0]
ldr r1, [r1,#0x18]
blx r1
ldr r1, [r4,#4]
movs r3, r0
ldr r0, [r1,#0x20]
movs r2, r5, lsr#9
mov r12, r0
ldr r0, [r4,#8]
str r7, [sp,#4]
adds r0, r0, r2
cmp r1, #0
str r6, [sp,#8]
str r0, [sp]
beq loc_801a668
adds r1, r1, #8
loc_801a668:
movs r2, r4
adds r2, r2, #0xC
mov r0, r12
ldr r5, =(sdmmc_unk2 + 1)
blx r5
stmfd sp!, {r0-r3}
ldr r2, =orig_sector
ldr r1, [r2]
str r1, [r4,#8]
ldr r1, [r2,#4]
str r1, [r4,#4]
ldmfd sp!, {r0-r3}
ldmfd sp!, {r1-r7,lr}
bx lr
.pool
orig_sector: .word 0x00000000
orig_ptr: .word 0x00000000
nand_offset: .ascii "NAND" ; for rednand this should be 1
ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED)
;ncsd_header_offset: .word 0x1D7800
;ncsd_header_offset: .word 0x1DD000
slot0x25keyX:
.word 0xABD8E7CE
.word 0xAE0DC030
.word 0xE3F50E85
.word 0xF35AAC82
.close

11
linker.ld Normal file
View File

@ -0,0 +1,11 @@
ENTRY(_start)
SECTIONS
{
. = 0x23F00000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

373
mset/LICENSE.txt Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

118
mset/Makefile Normal file
View File

@ -0,0 +1,118 @@
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
# This should be set externally
name ?= reiNand.dat
path ?=
dir_out ?= .
CC := arm-none-eabi-gcc
AS := arm-none-eabi-as
LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy
dir_source := source
dir_build := build
ARM9FLAGS := -mcpu=arm946e-s -march=armv5te
ARM11FLAGS := -mcpu=mpcore
ASFLAGS := -mlittle-endian
CFLAGS := -marm $(ASFLAGS) -O2 -std=c11 -MMD -MP -fno-builtin -fshort-wchar -Wall -Wextra -Wno-main -DLAUNCHER_PATH='"$(path)$(name)"'
get_objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, $1))
objects := $(call get_objects, $(wildcard $(dir_source)/*.s $(dir_source)/*.c))
objects_payload := $(call get_objects, \
$(call rwildcard, $(dir_source)/payload, *.s *.c))
versions := mset_4x mset_4x_dg mset_6x
rops := $(foreach ver, $(versions), $(dir_build)/$(ver)/rop.dat)
.SECONDARY:
.PHONY: all
all: launcher
.PHONY: launcher
launcher: $(dir_out)/$(name)
.PHONY: bigpayload
bigpayload: $(dir_build)/bigpayload.built
.PHONY: clean
clean:
rm -rf $(dir_out)/$(name) $(dir_build)
# Big payload
$(dir_build)/bigpayload.built: $(dir_out)/$(name) $(dir_build)/payload/main.bin
dd if=$(dir_build)/payload/main.bin of=$(dir_out)/$(name) bs=512 seek=144
@touch $@
# Throw everything together
$(dir_out)/$(name): $(rops) $(dir_build)/mset/main.bin $(dir_build)/spider/main.bin
touch $@
dd if=$(dir_build)/spider/main.bin of=$@ bs=512 seek=0
dd if=$(dir_build)/mset_4x/rop.dat of=$@ bs=512 seek=32
dd if=$(dir_build)/mset_4x_dg/rop.dat of=$@ bs=512 seek=34
dd if=$(dir_build)/mset_6x/rop.dat of=$@ bs=512 seek=40
dd if=$(dir_build)/mset/main.bin of=$@ bs=512 seek=64
# MSET ROPs
$(dir_build)/mset_%/rop.dat: rop_param = MSET_$(shell echo $* | tr a-z A-Z)
$(dir_build)/mset_%/rop.dat:
@make -C rop3ds LoadCodeMset.dat ASFLAGS="-D$(rop_param) -DARM_CODE_OFFSET=0x8000"
@mkdir -p "$(@D)"
@mv rop3ds/LoadCodeMset.dat $@
# Create bin from elf
$(dir_build)/%/main.bin: $(dir_build)/%/main.elf
$(OC) -S -O binary $< $@
# Different flags for different things
$(dir_build)/payload/main.elf: ASFLAGS := $(ARM9FLAGS) $(ASFLAGS)
$(dir_build)/payload/main.elf: CFLAGS := $(ARM9FLAGS) $(CFLAGS)
$(dir_build)/payload/main.elf: $(objects_payload)
# FatFs requires libgcc for __aeabi_uidiv
$(CC) -nostartfiles $(LDFLAGS) -T linker_payload.ld $(OUTPUT_OPTION) $^
# The arm11 payloads
$(dir_build)/%/main.elf: ASFLAGS := $(ARM11FLAGS) $(ASFLAGS)
$(dir_build)/mset/main.elf: CFLAGS := -DENTRY_MSET $(ARM11FLAGS) $(CFLAGS)
$(dir_build)/mset/main.elf: $(patsubst $(dir_build)/%, $(dir_build)/mset/%, $(objects))
$(LD) $(LDFLAGS) -T linker_mset.ld $(OUTPUT_OPTION) $^
$(dir_build)/spider/main.elf: CFLAGS := -DENTRY_SPIDER $(ARM11FLAGS) $(CFLAGS)
$(dir_build)/spider/main.elf: $(patsubst $(dir_build)/%, $(dir_build)/spider/%, $(objects))
$(LD) $(LDFLAGS) -T linker_spider.ld $(OUTPUT_OPTION) $^
# Fatfs requires to be built in thumb
$(dir_build)/payload/fatfs/%.o: $(dir_source)/payload/fatfs/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) -mthumb -mthumb-interwork -Wno-unused-function $(OUTPUT_OPTION) $<
$(dir_build)/payload/fatfs/%.o: $(dir_source)/payload/fatfs/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) -mthumb -mthumb-interwork $(OUTPUT_OPTION) $<
$(dir_build)/payload/%.o: $(dir_source)/payload/%.c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(dir_build)/payload/%.o: $(dir_source)/payload/%.s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
.SECONDEXPANSION:
$(dir_build)/%.o: $(dir_source)/$$(notdir $$*).c
@mkdir -p "$(@D)"
$(COMPILE.c) $(OUTPUT_OPTION) $<
.SECONDEXPANSION:
$(dir_build)/%.o: $(dir_source)/$$(notdir $$*).s
@mkdir -p "$(@D)"
$(COMPILE.s) $(OUTPUT_OPTION) $<
include $(call rwildcard, $(dir_build), *.d)

11
mset/linker_mset.ld Normal file
View File

@ -0,0 +1,11 @@
ENTRY(_start)
SECTIONS
{
. = 0x00240000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

11
mset/linker_payload.ld Normal file
View File

@ -0,0 +1,11 @@
ENTRY(_start)
SECTIONS
{
. = 0x23F00000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

11
mset/linker_spider.ld Normal file
View File

@ -0,0 +1,11 @@
ENTRY(_start)
SECTIONS
{
. = 0x009D2000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
}

BIN
mset/reiNand.dat Normal file

Binary file not shown.

View File

@ -0,0 +1,65 @@
.arm
.text
#include "rop.h"
#ifdef ARM_CODE
#define CODE_SIZE arm_code_end-arm_code
#else
#define CODE_SIZE 0x300*15-0x460
#endif
.global _start
@---------------------------------------------------------------------------------
_start:
rop_memcpy(BUFFER_LOC+0x300*0, ROP_LOC+0x304*1, 0x300)
rop_memcpy(BUFFER_LOC+0x300*1, ROP_LOC+0x304*2, 0x300)
rop_memcpy(BUFFER_LOC+0x300*2, ROP_LOC+0x304*3, 0x300)
rop_memcpy(BUFFER_LOC+0x300*3, ROP_LOC+0x304*4, 0x300)
rop_memcpy(BUFFER_LOC+0x300*4, ROP_LOC+0x1400+0x304*0, 0x300)
rop_memcpy(BUFFER_LOC+0x300*5, ROP_LOC+0x1400+0x304*1, 0x300)
rop_memcpy(BUFFER_LOC+0x300*6, ROP_LOC+0x1400+0x304*2, 0x300)
rop_memcpy(BUFFER_LOC+0x300*7, ROP_LOC+0x1400+0x304*3, 0x300)
rop_memcpy(BUFFER_LOC+0x300*8, ROP_LOC+0x1400+0x304*4, 0x300)
rop_memcpy(BUFFER_LOC+0x300*9, ROP_LOC+0x2800+0x304*0, 0x300)
rop_memcpy(BUFFER_LOC+0x300*10, ROP_LOC+0x2800+0x304*1, 0x300)
rop_memcpy(BUFFER_LOC+0x300*11, ROP_LOC+0x2800+0x304*2, 0x300)
rop_memcpy(BUFFER_LOC+0x300*12, ROP_LOC+0x2800+0x304*3, 0x300)
rop_memcpy(BUFFER_LOC+0x300*13, ROP_LOC+0x2800+0x304*4, 0x300)
rop_fs_mount(DMC)
.fill 3, 4, POP_PC
.word POP_R0_PC
@.org 0x21C
.word MAGIC
rop_flush_data_cache(BUFFER_LOC+arm_code-0x300, CODE_SIZE)
rop_gx_texture_copy(BUFFER_LOC+arm_code-0x300, CODE_TARGET, CODE_SIZE)
rop_flush_data_cache(BUFFER_LOC, 0x38400*2)
rop_gx_texture_copy(BUFFER_LOC, 0x1F48F000, 0x38400*2)
rop_sleep(1000000000)
@ rop_sleep(1000000000)
@ rop_flush_data_cache(BUFFER_LOC, 0x38400)
@ rop_gx_texture_copy(BUFFER_LOC, 0x1F4C7800, 0x38400)
@ rop_sleep(1000000000)
rop_jump_arm
.org 0x300
.org 0x3F4
.word ROP_LOC+_start+0x8C
.org 0x428
.word ROP_LOC+_start, 0, POP_PC
.org 0x458
.word POP_PC, POP_PC
arm_code:
#ifdef ARM_CODE
#define S_(x) #x
#define S(x) S_(x)
.incbin S(ARM_CODE)
#endif
arm_code_end:

7
mset/rop3ds/LICENSE Normal file
View File

@ -0,0 +1,7 @@
Copyright (c) 2015 dukesrg, bilis
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

34
mset/rop3ds/LoadCode.S Normal file
View File

@ -0,0 +1,34 @@
.arm
.text
#include "rop.h"
#ifndef SPIDER_ARM_CODE_SIZE
#define SPIDER_ARM_CODE_SIZE 0x00004000
#endif
.global _start
@---------------------------------------------------------------------------------
_start:
rop_fs_mount(DMC)
rop_file_open(THIS, FileName, FILE_READ)
rop_store(THIS+4, SPIDER_ARM_CODE_OFFSET)
rop_file_read(THIS, THIS+0x20, BUFFER_LOC, SPIDER_ARM_CODE_SIZE)
rop_flush_data_cache(BUFFER_LOC, SPIDER_ARM_CODE_SIZE)
rop_gx_texture_copy(BUFFER_LOC, CODE_TARGET, SPIDER_ARM_CODE_SIZE)
rop_sleep(1000000000)
rop_jump_arm
@.org 0x0F4, GARBAGE
.fill 3, 4, GARBAGE
.word ROP_LOC+_start+0x8C
@.org 0x128, GARBAGE
.fill 12, 4, GARBAGE
.word ROP_LOC+_start, 0, POP_PC
@.org 0x158, GARBAGE
.fill 9, 4, GARBAGE
.fill 2, 4, POP_PC
FileName:
.string16 "dmc:/"
@.org 0x21C, GARBAGE
.fill 44, 4, GARBAGE
.word MAGIC

View File

@ -0,0 +1,18 @@
.arm
.text
#include "rop.h"
#ifndef MSET_ARM_CODE_SIZE
#define MSET_ARM_CODE_SIZE 0x00004000
#endif
.global _start
@---------------------------------------------------------------------------------
_start:
rop_store(THIS+4, ARM_CODE_OFFSET)
rop_file_read(THIS, THIS+0x20, BUFFER_LOC, MSET_ARM_CODE_SIZE)
rop_flush_data_cache(BUFFER_LOC, MSET_ARM_CODE_SIZE)
rop_gx_texture_copy(BUFFER_LOC, CODE_TARGET, MSET_ARM_CODE_SIZE)
rop_sleep(1000000000)
rop_jump_arm

110
mset/rop3ds/Makefile Normal file
View File

@ -0,0 +1,110 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/base_rules
all: index.html compat.html rop.dat LoadCode.dat LoadCodeMset.dat
%.dat: %.elf
@$(OBJCOPY) -O binary $^ $@
%.elf: %.S
@$(CC) -c -o $@ $< $(ASFLAGS)
bin2utf8:
@gcc *.c -o bin2utf8.exe -std=c99
%.utf8: %.dat bin2utf8
@./bin2utf8.exe $< >$@
define makepayload
@echo "generating $(2) ROP"
@make -s LoadCode.dat ASFLAGS="-D$(2) -DSPIDER_ARM_CODE_OFFSET=$(3) -D$(4)"
@make -s LoadCode.utf8
@sed -e "/$(1)'/{rLoadCode.utf8" -e "N}" -i $(5)
@sed "/$(1)'/s/\(.*\)\(\t\{3\}.*:'\)/\2\1/" -i $(5)
@rm LoadCode.dat
@rm LoadCode.utf8
endef
index.html: index.html.template bin2utf8
@cp -f $< $@
$(call makepayload,17498,SPIDER_4X,0,NO_SPIDER_DG,$@)
$(call makepayload,17538C45,SPIDER_45_CN,0,NO_SPIDER_DG,$@)
$(call makepayload,17538C42,SPIDER_42_CN,0,NO_SPIDER_DG,$@)
$(call makepayload,17538K,SPIDER_4X_KR,0,NO_SPIDER_DG,$@)
$(call makepayload,17538T,SPIDER_4X_TW,0,NO_SPIDER_DG,$@)
$(call makepayload,17552,SPIDER_5X,0,NO_SPIDER_DG,$@)
$(call makepayload,17552C,SPIDER_5X_CN,0,NO_SPIDER_DG,$@)
$(call makepayload,17552K,SPIDER_5X_KR,0,NO_SPIDER_DG,$@)
$(call makepayload,17552T,SPIDER_5X_TW,0,NO_SPIDER_DG,$@)
$(call makepayload,17567,SPIDER_9X,0,NO_SPIDER_DG,$@)
$(call makepayload,17567C,SPIDER_9X_CN,0,NO_SPIDER_DG,$@)
$(call makepayload,17567K,SPIDER_9X_KR,0,NO_SPIDER_DG,$@)
$(call makepayload,17567T,SPIDER_9X_TW,0,NO_SPIDER_DG,$@)
compat.html: index.html.template bin2utf8
@cp -f $< $@
$(call makepayload,17498,SPIDER_4X,0,SPIDER_DG,$@)
$(call makepayload,17538C45,SPIDER_45_CN,0,SPIDER_DG,$@)
$(call makepayload,17538C42,SPIDER_42_CN,0,SPIDER_DG,$@)
$(call makepayload,17538K,SPIDER_4X_KR,0,SPIDER_DG,$@)
$(call makepayload,17538T,SPIDER_4X_TW,0,SPIDER_DG,$@)
define makebigpayload
@echo "generating $(2) ROP"
@./bin2utf8.exe $(1).rop >rop.utf8
@sed -e "/$(1)'/{rrop.utf8" -e "N}" -i $(5)
@sed "/$(1)'/s/\(.*\)\(\t\{3\}.*:'\)/\2\1/" -i $(5)
@rm rop.utf8
endef
big.html: index.html.template bin2utf8
@cp -f $< $@
$(call makebigpayload,17498,SPIDER_4X,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17538C45,SPIDER_45_CN,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17538C42,SPIDER_42_CN,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17538K,SPIDER_4X_KR,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17538T,SPIDER_4X_TW,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17552,SPIDER_5X,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17552C,SPIDER_5X_CN,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17552K,SPIDER_5X_KR,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17552T,SPIDER_5X_TW,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17567,SPIDER_9X,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17567C,SPIDER_9X_CN,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17567K,SPIDER_9X_KR,0,NO_SPIDER_DG,$@)
$(call makebigpayload,17567T,SPIDER_9X_TW,0,NO_SPIDER_DG,$@)
define makedatpayload
@echo "generating $(2) ROP"
@make -s DownloadCode.dat ASFLAGS="-D$(2) -DSPIDER_ARM_CODE_OFFSET=$(3) -D$(4)"
@mv DownloadCode.dat $(1).dat
endef
datpayload: download.html.template
$(call makedatpayload,17498,SPIDER_4X,0,NO_SPIDER_DG)
$(call makedatpayload,17538C45,SPIDER_45_CN,0,NO_SPIDER_DG)
$(call makedatpayload,17538C42,SPIDER_42_CN,0,NO_SPIDER_DG)
$(call makedatpayload,17538K,SPIDER_4X_KR,0,NO_SPIDER_DG)
$(call makedatpayload,17538T,SPIDER_4X_TW,0,NO_SPIDER_DG)
$(call makedatpayload,17552,SPIDER_5X,0,NO_SPIDER_DG)
$(call makedatpayload,17552C,SPIDER_5X_CN,0,NO_SPIDER_DG)
$(call makedatpayload,17552K,SPIDER_5X_KR,0,NO_SPIDER_DG)
$(call makedatpayload,17552T,SPIDER_5X_TW,0,NO_SPIDER_DG)
$(call makedatpayload,17567,SPIDER_9X,0,NO_SPIDER_DG)
$(call makedatpayload,17567C,SPIDER_9X_CN,0,NO_SPIDER_DG)
$(call makedatpayload,17567K,SPIDER_9X_KR,0,NO_SPIDER_DG)
$(call makedatpayload,17567T,SPIDER_9X_TW,0,NO_SPIDER_DG)
@cp -f $< download.html
datpayloadcompat: download.html.template
$(call makedatpayload,17498,SPIDER_4X,0,SPIDER_DG)
$(call makedatpayload,17538C45,SPIDER_45_CN,0,SPIDER_DG)
$(call makedatpayload,17538C42,SPIDER_42_CN,0,SPIDER_DG)
$(call makedatpayload,17538K,SPIDER_4X_KR,0,SPIDER_DG)
$(call makedatpayload,17538T,SPIDER_4X_TW,0,SPIDER_DG)
@cp -f $< download.html
.PHONY: clean
clean:
@rm -rf *.elf *.dat *.rop *.exe *.utf8 *.html

43
mset/rop3ds/bin2utf8.c Normal file
View File

@ -0,0 +1,43 @@
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *file;
unsigned int state;
unsigned short data, prevdata = 1;
if (argc != 2)
{
fprintf(stderr, "Usage: %s input-file\n", argv[0]);
return 255;
}
if ((file = fopen(argv[1], "rb")) == NULL)
{
perror("fopen");
return 1;
}
while (fread(&data, 2, 1, file) == 1)
{
if (data == 0){
printf("\\0");
}else if (data == '\r' || data == '\n'){
printf("\\%03o", data);
}else if (((prevdata == 0) && (data >= '0') && (data <= '7'))){
printf("00%c", data);
}else if ((data == '\'') || /*(data == '"') ||*/ (data == '\\')){
printf("\\%c", (char)data);
}else if (data == 0x2028 || ((data >= 0xD800) && (data <= 0xDFFF))){
printf("\\u%04x", data);
}else if (data < 0x80){
printf("%c", (char)data);
}else if (data < 0x800){
printf("%c%c", ((data >> 6) & 0x1F) | 0xC0, (data & 0x3F) | 0x80);
}else{
printf("%c%c%c", ((data >> 12) & 0x0F) | 0xE0, ((data >> 6) & 0x3F) | 0x80, ((data) & 0x3F) | 0x80);
}
prevdata = data;
}
fclose(file);
return 0;
}

BIN
mset/rop3ds/bin2utf8.exe Normal file

Binary file not shown.

51
mset/rop3ds/compat.html Normal file
View File

@ -0,0 +1,51 @@
<html><head><script>
d=document,r=parent,w=window,n=navigator.userAgent;
if(r==w){
l='arm.dat',u=decodeURI(d.URL),g=u.split('?');
if(g.length>1){
g=g[1].split('&');
if(g[0].length>0&&g[0].length<25)l=g[0];
}
d.title='Load '+l;
w.onload=function(){
if(n.indexOf('1.7538.CN')>=0)n=n.replace('.CN',confirm('系统版本4.2-4.4选择OK系统版本4.5选择取消。')?'.CN.42':'.CN.45');
d.body.childNodes[0].innerHTML=l+' loading<iframe height=0 src=#/>';
}
}else{
w.onload=function(){
b=0,f=w.frameElement,p=f.parentNode,o=d.createElement('object');
o.addEventListener('beforeload',function(){
if(++b==1)p.addEventListener('DOMSubtreeModified',r.z);
else if(b==2)p.removeChild(f);
});
d.body.appendChild(o);
}
}
function z(){
if(n.indexOf('Nintendo 3DS')>=0){
m=[],q={'17412':'',
'17455':'',
'17498':'樴-\udb6c해*弧*⯨3樴-\udb6c해*찀ॸ瑐!畠ࢴ\0@#낤%해*찄ॸ靘&\0\0鮔@#樴-\udb6c해*찀ॸ瑐!찠ॸ\0ᡁ䀀\0죤/樴-\udb6c해*搼;瑐!老￿\0ᡁ䀀\0䰬4해*啀?靘&璬ࢴ,\0\0ᡁကᥝ䀀\0￿￿해*\0樴-\udb6c해*쨀㮚靘&\0\0儼* @#@#@#璌ࢴ@#@#@#@#@#@#@#@#@#@#@#@#琀ࢴ\0\0\udb6c@#@#@#@#@#@#@#@#@#\udb6c\udb6cdmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#樜-',
'17538C42':'ﺘ찀ॸ㷈Š࣌\0@#"싸찄ॸ欬"\0\0暄@#ﺘ찀ॸ㷈찠ॸ\0ᡁ䀀\0璼霄=㷈老￿\0ᡁ䀀\0봜沘=欬"¬࣌멄\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﺘ쨀㮚欬"\0\0䈘 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺀ',
'17538C45':'ﺨ찀ॸ㷀Š࣌\0@#"쌤찄ॸ櫸"\0\0暴@#ﺨ찀ॸ㷀찠ॸ\0ᡁ䀀\0濈霄=㷀老￿\0ᡁ䀀\0봰沘=櫸"¬࣌멘\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﺨ쨀㮚櫸"\0\0䈌 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0埤@#@#@#@#@#@#@#@#@#埤dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺐ',
'17538K':'﹬찀ॸ㷈Š࣍\0@#"싸찄ॸ稨"\0\0暄@#﹬찀ॸ㷈찠ॸ\0ᡁ䀀\0胸꜄=㷈老￿\0ᡁ䀀\0볰粘=稨"¬࣍먘\0\0ᡁ ᥙ䀀\0￿￿￿￿\0﹬쨀㮚稨"\0\0䈘 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#﹔',
'17538T':'ﺘ찀ॸ㷈Š࣍\0@#"싸찄ॸ穤"\0\0暄@#ﺘ찀ॸ㷈찠ॸ\0ᡁ䀀\0胼꜄=㷈老￿\0ᡁ䀀\0봜粘=穤"¬࣍멄\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﺘ쨀㮚穤"\0\0䈘 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺀ',
'17552':'',
'17552C':'',
'17552K':'',
'17552T':'',
'17567':'',
'17567C':'',
'17567K':'',
'17567T':''
}[n.split('/').pop().replace(/[^\dCKT]/g,'')],
s=q.indexOf("dmc:/")+5;
q=q.substring(0,s)+l+"\0"+q.slice(s+l.length+1);
q+=Array(384-q.length+1+1).join('\0');
for(j=1;j<410;j++){
i=j/96,a=Array(j);
for(k=0;k<i;a[k++]=q);
m.push(d.createTextNode(String.fromCharCode.apply(null,Array(a))));
}
}
}</script></head><body><h1>.</h1></body></html>

View File

@ -0,0 +1,71 @@
<html><head><script>
d=document,r=parent,w=window,n=navigator.userAgent;
if(r==w){
l='reiNand.dat',g=decodeURI(d.URL).split('?');
if(g.length>1){
g=g[1].split('&');
if(g[0].length>0&&g[0].length<25)l=g[0];
}
d.title='Load '+l;
w.onload=function(){
if(n.indexOf('1.7538.CN')>=0)n=n.replace('.CN',confirm('系统版本4.2-4.4选择OK系统版本4.5选择取消。')?'.CN.42':'.CN.45');
var h=d.body.childNodes[0];
var v=n.split('/').pop().replace(/[^\dCKT]/g,'')+'.rop';
h.innerHTML='Downloading payload '+v+': ';
var x=new XMLHttpRequest();
x.open('GET',v,true);
x.overrideMimeType('text/plain; charset=x-user-defined');
x.onload=function(){
if(x.status==200){
var u='OK<br>Patching filename to '+l+': ';
var s=x.responseText;
var y=s.length;
var t=Array(y<768?768:y);
for(i=0;i<y;t[i]=s.charCodeAt(i)&255,i++);
y=t.length>>1;
for(i=0;i<y;t[i]=t[i*2]|t[i*2+1]<<8,i++);
t.length>>=1;
s=String.fromCharCode.apply(null,t);
y=s.indexOf('dmc:/')+5;
if(y>4){
s=s.substring(0,y)+l+'\0'+s.slice(y+l.length+1);
u+='OK';
}else{
u+='skipped';
}
if(s.length<=384)s+=Array(384-s.length+1).join('\0')+s;
s+=Array(384*15-s.length+1+1).join('\0');
q=[];
for(k=0,i=0;k<15;q[k++]=s.substring(i,i+385),i+=384);
u+='<br>Executing payload...<iframe height=0 src=#/>';
}else{
u='failed';
}
h.innerHTML+=u;
}
x.send();
}
}else{
w.onload=function(){
b=0,f=w.frameElement,p=f.parentNode,o=d.createElement('object');
o.addEventListener('beforeload',function(){
if(++b==1)p.addEventListener('DOMSubtreeModified',r.z);
else if(b==2)p.removeChild(f);
});
d.body.appendChild(o);
}
}
function z(){
if(n.indexOf('Nintendo 3DS')>=0){
m=[];
for(j=0;j<410;j++){
a=Array(j);
if(384<j&&j<388){
for(k=0,i=(j-385)*5;k<5;a[k++]=q[i++]);
}else{
for(k=0,i=j/96;k<i;a[k++]=q[1]);
}
m.push(d.createTextNode(String.fromCharCode.apply(null,Array(a))));
}
}
}</script></head><body><h1>.</h1></body></html>

51
mset/rop3ds/index.html Normal file
View File

@ -0,0 +1,51 @@
<html><head><script>
d=document,r=parent,w=window,n=navigator.userAgent;
if(r==w){
l='arm.dat',u=decodeURI(d.URL),g=u.split('?');
if(g.length>1){
g=g[1].split('&');
if(g[0].length>0&&g[0].length<25)l=g[0];
}
d.title='Load '+l;
w.onload=function(){
if(n.indexOf('1.7538.CN')>=0)n=n.replace('.CN',confirm('系统版本4.2-4.4选择OK系统版本4.5选择取消。')?'.CN.42':'.CN.45');
d.body.childNodes[0].innerHTML=l+' loading<iframe height=0 src=#/>';
}
}else{
w.onload=function(){
b=0,f=w.frameElement,p=f.parentNode,o=d.createElement('object');
o.addEventListener('beforeload',function(){
if(++b==1)p.addEventListener('DOMSubtreeModified',r.z);
else if(b==2)p.removeChild(f);
});
d.body.appendChild(o);
}
}
function z(){
if(n.indexOf('Nintendo 3DS')>=0){
m=[],q={'17412':'',
'17455':'',
'17498':'樴-\udb6c해*弧*⯨3樴-\udb6c해*찀ॸ瑐!畠ࢴ\0@#낤%해*찄ॸ靘&\0\0鮔@#樴-\udb6c해*찀ॸ瑐!찠ॸ\0ᡁ䀀\0죤/樴-\udb6c해*搼;瑐!老￿\0ᡁ䀀\0䰬4해*啀?靘&璬ࢴ,\0\0ᡁ ᤭䀀\0￿￿해*\0樴-\udb6c해*쨀㮚靘&\0\0儼* @#@#@#璌ࢴ@#@#@#@#@#@#@#@#@#@#@#@#琀ࢴ\0\0\udb6c@#@#@#@#@#@#@#@#@#\udb6c\udb6cdmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#樜-',
'17538C42':'ﺘ찀ॸ㷈Š࣌\0@#"싸찄ॸ欬"\0\0暄@#ﺘ찀ॸ㷈찠ॸ\0ᡁ䀀\0璼霄=㷈老￿\0ᡁ䀀\0봜沘=欬"¬࣌멄\0\0ᡁ瀀ᤵ䀀\0￿￿￿￿\0ﺘ쨀㮚欬"\0\0䈘 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺀ',
'17538C45':'ﺨ찀ॸ㷀Š࣌\0@#"쌤찄ॸ櫸"\0\0暴@#ﺨ찀ॸ㷀찠ॸ\0ᡁ䀀\0濈霄=㷀老￿\0ᡁ䀀\0봰沘=櫸"¬࣌멘\0\0ᡁ瀀ᤵ䀀\0￿￿￿￿\0ﺨ쨀㮚櫸"\0\0䈌 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0埤@#@#@#@#@#@#@#@#@#埤dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺐ',
'17538K':'﹬찀ॸ㷈Š࣍\0@#"싸찄ॸ稨"\0\0暄@#﹬찀ॸ㷈찠ॸ\0ᡁ䀀\0胸꜄=㷈老￿\0ᡁ䀀\0볰粘=稨"¬࣍먘\0\0ᡁ倀ᤥ䀀\0￿￿￿￿\0﹬쨀㮚稨"\0\0䈘 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#﹔',
'17538T':'ﺘ찀ॸ㷈Š࣍\0@#"싸찄ॸ穤"\0\0暄@#ﺘ찀ॸ㷈찠ॸ\0ᡁ䀀\0胼꜄=㷈老￿\0ᡁ䀀\0봜粘=穤"¬࣍멄\0\0ᡁ倀ᤵ䀀\0￿￿￿￿\0ﺘ쨀㮚穤"\0\0䈘 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0垴@#@#@#@#@#@#@#@#@#垴dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺀ',
'17552':'ΤΤ찀ॸ㷀啠ࢸ\0@#﹄"쌠찄ॸ謐"\0\0暰@#Τ찀ॸ㷀찠ॸ\0ᡁ䀀\0蛀ΤꜬ=㷀老￿\0ᡁ䀀\0숨粘=謐"咬ࢸ뽐\0\0ᡁ ᥙ䀀\0￿￿￿￿\0Τ쨀㮚謐"\0\0䈌 @#@#@#和ࢸ@#@#@#@#@#@#@#@#@#@#@#@#吀ࢸ\0\0埠@#@#@#@#@#@#@#@#@#埠dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#Ό',
'17552C':'ﻀ찀ॸ㷀Š࣌\0@#"쌠찄ॸ犠"\0\0暰@#ﻀ찀ॸ㷀찠ॸ\0ᡁ䀀\0甜꜌=㷀老￿\0ᡁ䀀\0뵈粘=犠"¬࣌며\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﻀ쨀㮚犠"\0\0䈌 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0埠@#@#@#@#@#@#@#@#@#埠dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺨ',
'17552K':'ﺔ찀ॸ㷀Š࣍\0@#靖"쌠찄ॸ艴"\0\0暰@#ﺔ찀ॸ㷀찠ॸ\0ᡁ䀀\0蛼꜌=㷀老￿\0ᡁ䀀\0봜粘=艴"¬࣍멄\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﺔ쨀㮚艴"\0\0䈌 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0埠@#@#@#@#@#@#@#@#@#埠dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﹼ',
'17552T':'ﻀ찀ॸ㷀Š࣍\0@#ﭜ"쌠찄ॸ苰"\0\0暰@#ﻀ찀ॸ㷀찠ॸ\0ᡁ䀀\0蝄꜌=㷀老￿\0ᡁ䀀\0뵈粘=苰"¬࣍며\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﻀ쨀㮚苰"\0\0䈌 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0埠@#@#@#@#@#@#@#@#@#埠dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#ﺨ',
'17567':'͜͜찀ॸ㶬蕠ࢸ\0@#"싼찄ॸ諴"\0\0暔@#͜찀ॸ㶬찠ॸ\0ᡁ䀀\0蛜͜Ꜭ=㶬老￿\0ᡁ䀀\0쇠粘=諴"蒬ࢸ뼈\0\0ᡁ ᥙ䀀\0￿￿￿￿\0͜쨀㮚諴"\0\0䇸 @#@#@#蒌ࢸ@#@#@#@#@#@#@#@#@#@#@#@#萀ࢸ\0\0埄@#@#@#@#@#@#@#@#@#埄dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#̈́',
'17567C':'ﹸ찀ॸ㶬Š࣌\0@#"싼찄ॸ犌"\0\0暔@#ﹸ찀ॸ㶬찠ॸ\0ᡁ䀀\0畀꜌=㶬老￿\0ᡁ䀀\0봀粘=犌"¬࣌먨\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﹸ쨀㮚犌"\0\0䇸 @#@#@#Œ࣌@#@#@#@#@#@#@#@#@#@#@#@#\0࣌\0\0埄@#@#@#@#@#@#@#@#@#埄dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#﹠',
'17567K':'﹌찀ॸ㶬Š࣍\0@#戴"싼찄ॸ艜"\0\0暔@#﹌찀ॸ㶬찠ॸ\0ᡁ䀀\0蜘꜌=㶬老￿\0ᡁ䀀\0볔粘=艜"¬࣍맼\0\0ᡁ ᥙ䀀\0￿￿￿￿\0﹌쨀㮚艜"\0\0䇸 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0埄@#@#@#@#@#@#@#@#@#埄dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#︴',
'17567T':'ﹸ찀ॸ㶬Š࣍\0@#ﬠ"싼찄ॸ苘"\0\0暔@#ﹸ찀ॸ㶬찠ॸ\0ᡁ䀀\0蝠꜌=㶬老￿\0ᡁ䀀\0봀粘=苘"¬࣍먨\0\0ᡁ ᥙ䀀\0￿￿￿￿\0ﹸ쨀㮚苘"\0\0䇸 @#@#@#Œ࣍@#@#@#@#@#@#@#@#@#@#@#@#\0࣍\0\0埄@#@#@#@#@#@#@#@#@#埄dmc:/\0@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#﹠'
}[n.split('/').pop().replace(/[^\dCKT]/g,'')],
s=q.indexOf("dmc:/")+5;
q=q.substring(0,s)+l+"\0"+q.slice(s+l.length+1);
q+=Array(384-q.length+1+1).join('\0');
for(j=1;j<410;j++){
i=j/96,a=Array(j);
for(k=0;k<i;a[k++]=q);
m.push(d.createTextNode(String.fromCharCode.apply(null,Array(a))));
}
}
}</script></head><body><h1>.</h1></body></html>

View File

@ -0,0 +1,51 @@
<html><head><script>
d=document,r=parent,w=window,n=navigator.userAgent;
if(r==w){
l='arm.dat',u=decodeURI(d.URL),g=u.split('?');
if(g.length>1){
g=g[1].split('&');
if(g[0].length>0&&g[0].length<25)l=g[0];
}
d.title='Load '+l;
w.onload=function(){
if(n.indexOf('1.7538.CN')>=0)n=n.replace('.CN',confirm('系统版本4.2-4.4选择OK系统版本4.5选择取消。')?'.CN.42':'.CN.45');
d.body.childNodes[0].innerHTML=l+' loading<iframe height=0 src=#/>';
}
}else{
w.onload=function(){
b=0,f=w.frameElement,p=f.parentNode,o=d.createElement('object');
o.addEventListener('beforeload',function(){
if(++b==1)p.addEventListener('DOMSubtreeModified',r.z);
else if(b==2)p.removeChild(f);
});
d.body.appendChild(o);
}
}
function z(){
if(n.indexOf('Nintendo 3DS')>=0){
m=[],q={'17412':'',
'17455':'',
'17498':'',
'17538C42':'',
'17538C45':'',
'17538K':'',
'17538T':'',
'17552':'',
'17552C':'',
'17552K':'',
'17552T':'',
'17567':'',
'17567C':'',
'17567K':'',
'17567T':''
}[n.split('/').pop().replace(/[^\dCKT]/g,'')],
s=q.indexOf("dmc:/")+5;
q=q.substring(0,s)+l+"\0"+q.slice(s+l.length+1);
q+=Array(384-q.length+1+1).join('\0');
for(j=1;j<410;j++){
i=j/96,a=Array(j);
for(k=0;k<i;a[k++]=q);
m.push(d.createTextNode(String.fromCharCode.apply(null,Array(a))));
}
}
}</script></head><body><h1>.</h1></body></html>

21
mset/rop3ds/rop.S Normal file
View File

@ -0,0 +1,21 @@
.arm
.text
#include "rop.h"
.global _start
@---------------------------------------------------------------------------------
_start:
rop_memcpy(BUFFER_LOC, ROP_LOC+arm_code, arm_code_end-arm_code)
rop_flush_data_cache(BUFFER_LOC, arm_code_end-arm_code)
rop_gx_texture_copy(BUFFER_LOC, CODE_TARGET, arm_code_end-arm_code)
rop_sleep(1000000000)
rop_jump_arm
.align 4, GARBAGE
arm_code:
#ifdef ARM_CODE
#define S_(x) #x
#define S(x) S_(x)
.incbin S(ARM_CODE)
#endif
arm_code_end:

541
mset/rop3ds/rop.h Normal file
View File

@ -0,0 +1,541 @@
#define DLPLAY_CODE_LOC_VA 0x00192800
#define DLPLAY_NSSHANDLE_LOC_VA 0x001A5200
#define KPROCESS_HANDLE 0xFFFF8001
#define GX_SetTextureCopy 0x00000004
#define FILE_READ 0x00000001
#define FILE_WRITE 0x00000002
#define FILE_CREATE 0x00000004
#define GARBAGE 0x00230040
#if defined(MSET_4X) || defined(MSET_4X_DG)
#define ROP_LOC 0x002B0000
#define HANDLE_PTR 0x0027FAC4
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0013C5D4
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x0027C580
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x001AC924
#define LDR_R0_0_POP_R4_PC 0x0012FBBC
#define POP_PC 0x001002F9
#define POP_R0_PC 0x00143D8C
#define POP_R1_PC 0x001C4FC4
// #define POP_R1_PC 0x001549E1
#define POP_R2_PC 0x0022952D
#define POP_R3_PC 0x0010538C
#define POP_R4_PC 0x001001ED
// #define POP_R4_PC 0x001B3AA0
#define POP_R0_R2_PC 0x0010F2B9
#define POP_R1_2_3_PC 0x001549B1
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x0018D5DC
#define POP_R4_LR_BX_R2 0x001D9360
#define STR_R1_0_POP_R4_PC 0x0010CCBC
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x001B82A8
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001B3954
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001B3B50
#define SVC_0A_BX_LR 0x001AEA50
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x001BFA60
#if defined(MSET_4X_DG) || defined(MSET_DG)
#define CODE_TARGET 0x17EB0000
#else
#define CODE_TARGET 0x17FAD000
#endif
#elif defined(MSET_6X)
#define ROP_LOC 0x00290000
#define HANDLE_PTR 0x0028DBEC
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0013D3FC
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x0028A580
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x001B4E8C
#define LDR_R0_0_POP_R4_PC 0x00130818
#define POP_PC 0x001002F9
#define POP_R0_PC 0x00144CF8
#define POP_R1_2_3_PC 0x0011BE4D
#define POP_R1_PC 0x001CD804
#define POP_R3_PC 0x00105110
#define POP_R4_PC 0x001001ED
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x0018B184
#define POP_R4_LR_BX_R2 0x00192758
#define STR_R1_0_POP_R4_PC 0x0010CF5C
#define SVC_0A_BX_LR 0x001B6C6C
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x001C08B4
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001BC188
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001BC380
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x001C814C
#define CODE_TARGET 0x17EA0000
#elif defined(SPIDER_20) //1.7412.JP/US/EU
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x0017E63C
#define LDMFD_SP_R4_5_PC 0x00101418
#define LDR_R0_0_POP_R4_PC 0x001CA228
#define POP_PC 0x0010D8B4
#define POP_R0_1_2_3_4_7_PC 0x001768FF
#define POP_R1_PC 0x0026A124
#define POP_R4_5_6_PC 0x00100D24
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x00103D3C
#define SP_LR_LDMFD_SP_LR_PC 0x002D5254
#define STR_R1_0_POP_R4_PC 0x00119768
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x00332EBC
#define IFile_Open_LDMFD_SP_R4_5_6_7_PC 0x0025B8AC
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x002FA3F0
#define DMC 0x002A497F
#define MAGIC 0x002D5240
#define ROP_LOC 0x08CF2000
#ifdef SPIDER_DG
#define CODE_TARGET 0x195CE000
#else
#define CODE_TARGET 0x192CD000
#endif
#elif defined(SPIDER_21) //1.7455.JP/US/EU
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x0017E764
#define LDMFD_SP_R4_5_PC 0x00101418
#define LDR_R0_0_POP_R4_PC 0x001CA350
#define POP_PC 0x0010D954
#define POP_R0_1_2_3_4_7_PC 0x00176A27
#define POP_R1_PC 0x0026A528
#define POP_R4_5_6_PC 0x00100D24
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x00103D3C
#define SP_LR_LDMFD_SP_LR_PC 0x002D5654
#define STR_R1_0_POP_R4_PC 0x00119864
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x00333330
#define IFile_Open_LDMFD_SP_R4_5_6_7_PC 0x0025BC00
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x002FA864
#define DMC 0x002A4C57
#define MAGIC 0x002D5640
#define ROP_LOC 0x08CF2000
#ifdef SPIDER_DG
#define CODE_TARGET 0x195CE000
#else
#define CODE_TARGET 0x192CD000
#endif
#elif defined(SPIDER_4X) //1.7498.JP/US/EU
#define DLPLAY_CODE_LOC (DLPLAY_CODE_LOC_VA-0x00100000+0x03F50000+0x14000000-0x4000)
#define DLPLAY_HOOK_LOC (0x1A3500-0x00100000+0x03F50000+0x14000000-0x4000)
#define HANDLE_PTR 0x003B643C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x00344C2C
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003F54E8
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_PC 0x002CF3EC
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x00354850
#define CALL_BX_LR 0x0025DFF0
#define CALL_BX_LR_2 0x00344B84
#define CALL_3 0x002C62E4
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x0018114C
#define LDMFD_SP_R4_5_PC 0x00101408
#define LDR_R0_0_POP_R4_PC 0x001CCC64
#define POP_LR_PC 0x002D6A34
#define POP_PC 0x0010DB6C
#define POP_R0_PC 0x002AD574
#define POP_R1_2_3_PC 0x00217450
#define POP_R0_1_2_3_4_PC 0x0029C170
// #define POP_R0_1_2_3_4_PC 0x0022B550
#define POP_R0_1_2_3_4_7_PC 0x0017943B
#define POP_R1_PC 0x00269758
#define POP_R2_PC 0x0012F815
#define POP_R2_3_PC 0x00231A24
#define POP_R2_3_4_PC 0x00101878
#define POP_R3_PC 0x0011B064
#define POP_R4_PC 0x0010DAA8
#define POP_R4_5_6_PC 0x00100D24
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x00103DA8
#define POP_R4_LR_BX_R2 0x00100C8C
#define SP_LR_LDMFD_SP_LR_PC 0x002D6A30
#define STR_R1_0_POP_R4_PC 0x00119B94
// #define STR_R1_0_POP_R4_PC 0x0016F3FC
#define SVC_0A_BX_LR 0x002A513C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x00332BE8
#define IFile_Open_LDMFD_SP_R4_5_6_7_PC 0x0025B0A4
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x002FC8E4
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00311D90
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0029BF60
#define DMC 0x002A5F27
#define MAGIC 0x002D6A1C
#define ROP_LOC 0x08B47400
// #define ROP_LOC 0x08CF2000
#ifdef SPIDER_DG
#define CODE_TARGET 0x195D1000
#else
#define CODE_TARGET 0x192D3000
#endif
#elif defined(SPIDER_42_CN) || defined(SPIDER_4X_KR) || defined(SPIDER_4X_TW) //1.7538.CN/KR/TW
#define CALL_3 0x0011DD48
#define DMC 0x0010509F //CN?
#define LDMFD_SP_R4_5_PC 0x00101A44
#define LDR_R0_0_POP_R4_PC 0x0011BADC
#define POP_PC 0x001057B4
#define POP_R0_PC 0x0010C2F8
#define POP_R3_PC 0x001050D4
#define POP_R1_2_3_PC 0x00103DC8
#define POP_R4_5_6_PC 0x0010014C //CN?
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x00106598
#define STR_R1_0_POP_R4_PC 0x00106684
#if defined(SPIDER_42_CN) //1.7538.CN FW4.2
#define HANDLE_PTR 0x003D9704
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD1C
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D6C40
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA40
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023F048
#define SVC_0A_BX_LR 0x00104218
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019B640
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022E334
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001674BC
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00167544
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B7F18
#define CALL_BX_LR 0x0023E4DC
#define CALL_BX_LR_2 0x00190118
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C469C
#define POP_LR_PC 0x0012FE98
#define POP_R0_1_2_3_4_7_PC 0x001932FB
#define POP_R1_PC 0x00226B2C
#define POP_R2_3_PC 0x0014C734
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE94
#define MAGIC 0x0012FE80
#ifdef SPIDER_DG
#define CODE_TARGET 0x19593000
#else
#define CODE_TARGET 0x19357000
#endif
#elif defined(SPIDER_4X_KR) //1.7538.KR
#define HANDLE_PTR 0x003DA704
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BCF0
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D7C40
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA14
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023FF90
#define SVC_0A_BX_LR 0x00104218
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019C258
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022F284
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001680F8
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00168180
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B8B68
#define CALL_BX_LR 0x0023F424
#define CALL_BX_LR_2 0x00190D30
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C4EC4
#define POP_LR_PC 0x0012FE6C
#define POP_R0_1_2_3_4_7_PC 0x00193F13
#define POP_R1_PC 0x00227A28
#define POP_R2_3_PC 0x0014D2D8
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE68
#define MAGIC 0x0012FE54
#ifndef SPIDER_DG
#define CODE_TARGET 0x19255000
#endif
#elif defined(SPIDER_4X_TW) //1.7538.TW
#define HANDLE_PTR 0x003DA704
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD1C
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D7C40
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA40
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023FFE4
#define SVC_0A_BX_LR 0x00104218
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019C260
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022F2D8
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001680FC
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00168184
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B8B70
#define CALL_BX_LR 0x0023F478
#define CALL_BX_LR_2 0x00190D34
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C4F14
#define POP_LR_PC 0x0012FE98
#define POP_R0_1_2_3_4_7_PC 0x00193F1B
#define POP_R1_PC 0x00227A64
#define POP_R2_3_PC 0x0014D29C
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE94
#define MAGIC 0x0012FE80
#ifndef SPIDER_DG
#define CODE_TARGET 0x19355000
#endif
#endif
#elif defined(SPIDER_45_CN) //1.7538.CN FW4.5
#define CALL_3 0x0011DD68
#define DMC 0x001050CF
#define LDMFD_SP_R4_5_PC 0x00101A40
#define LDR_R0_0_POP_R4_PC 0x0011BB04
#define POP_LR_PC 0x0012FEA8
#define POP_PC 0x001057E4
#define POP_R0_PC 0x0010C324
#define POP_R1_PC 0x00226AF8
#define POP_R1_2_3_PC 0x00103DC0
#define POP_R2_3_PC 0x0014C26C
#define POP_R3_PC 0x00105104
// #define POP_R4_5_6_PC 0x?
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x001065C8
#define STR_R1_0_POP_R4_PC 0x001066B4
#define HANDLE_PTR 0x003D9704
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD30
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D6C40
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA54
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023EFA0
#define SVC_0A_BX_LR 0x0010420C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019B138
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022E2B0
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x00166FC8
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00167050
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C464C
#define CALL_BX_LR 0x0023E434
#define CALL_BX_LR_2 0x0018FC0C
#define POP_R0_1_2_3_4_7_PC 0x00112211
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B7A10
#define SP_LR_LDMFD_SP_LR_PC 0x0012FEA4
#define MAGIC 0x0012FE90
#ifdef SPIDER_DG
#define CODE_TARGET 0x19593000
#else
#define CODE_TARGET 0x19357000
#endif
#elif defined(SPIDER_5X) || defined(SPIDER_5X_CN) || defined(SPIDER_5X_KR) || defined(SPIDER_5X_TW)
#define CALL_3 0x0011DD80
#define DMC 0x001050CB
#define LDMFD_SP_R4_5_PC 0x00101A40
#define LDR_R0_0_POP_R4_PC 0x0011BB00
#define POP_PC 0x001057E0
#define POP_R0_PC 0x0010C320
#define POP_R1_2_3_PC 0x00103DC0
#define POP_R3_PC 0x00105100
#define POP_R4_5_6_PC 0x0010014C
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x001065C4
// #define POP_R4_5_6_7_8_9_10_11_12_PC 0x0010CC4C
#define STR_R1_0_POP_R4_PC 0x001066B0
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D7C40
#if defined(SPIDER_5X_CN) //1.7552.CN
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD48
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA6C
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023F80C
#define SVC_0A_BX_LR 0x0010420C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019B7D0
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022EA5C
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x0016751C
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001675A4
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B80A8
#define CALL_BX_LR 0x0023ECA0
#define CALL_BX_LR_2 0x001902A8
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C4E98
#define POP_LR_PC 0x0012FEC0
#define POP_R0_1_2_3_4_7_PC 0x0019348B
#define POP_R1_PC 0x002272A0
#define POP_R2_3_PC 0x0014C8AC
#define SP_LR_LDMFD_SP_LR_PC 0x0012FEBC
#define MAGIC 0x0012FEA8
#elif defined(SPIDER_5X_KR) //1.7552.KR
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD1C
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA40
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x002407DC
#define SVC_0A_BX_LR 0x0010420C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CA78
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FAC8
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001686FC
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00168784
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B9350
#define CALL_BX_LR 0x0023FC70
#define CALL_BX_LR_2 0x0019154C
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C5748
#define POP_LR_PC 0x0012FE94
#define POP_R0_1_2_3_4_7_PC 0x00194733
#define POP_R1_PC 0x00228274
#define POP_R2_3_PC 0x0014D49C
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE90
#define MAGIC 0x0012FE7C
#elif defined(SPIDER_5X_TW) //1.7552.TW
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD48
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA6C
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x00240870
#define SVC_0A_BX_LR 0x0010420C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CAC0
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FB5C
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x00168744
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001687CC
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B9398
#define CALL_BX_LR 0x0023FD04
#define CALL_BX_LR_2 0x00191594
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C57D8
#define POP_LR_PC 0x0012FEC0
#define POP_R0_1_2_3_4_7_PC 0x0019477B
#define POP_R1_PC 0x002282F0
#define POP_R2_3_PC 0x0014D4A4
#define SP_LR_LDMFD_SP_LR_PC 0x0012FEBC
#define MAGIC 0x0012FEA8
#else //1.7552.JP/US/EU
#define DLPLAY_CODE_LOC (DLPLAY_CODE_LOC_VA-0x00100000+0x03F50000+0x14000000)
#define DLPLAY_HOOK_LOC (0x1A3500-0x00100000+0x03F50000+0x14000000)
#define HANDLE_PTR 0x003DA72C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012C228
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BF4C
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B9300
#define CALL_BX_LR 0x0023FFEC
#define CALL_BX_LR_2 0x001914FC
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C5AC0
#define POP_LR_PC 0x001303A4
#define POP_R0_1_2_3_4_PC 0x0012A3D4
#define POP_R0_1_2_3_4_7_PC 0x001946E3
#define POP_R1_PC 0x00228B10
#define POP_R2_3_PC 0x0014D554
#define POP_R2_3_4_PC 0x001007B4
#define POP_R4_PC 0x0010510C
#define SP_LR_LDMFD_SP_LR_PC 0x001303A0
#define SVC_0A_BX_LR 0x0010420C
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CA28
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FE44
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001686C0
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00168748
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x00240B58
#define MAGIC 0x0013038C
#define ROP_LOC 0x08B85400
// #define ROP_LOC 0x088B5400
// #define ROP_LOC 0x08CF208C
#endif
#elif defined(SPIDER_9X) || defined(SPIDER_9X_CN) || defined(SPIDER_9X_KR) || defined(SPIDER_9X_TW)
#define CALL_3 0x0011DD48
#define DMC 0x001050B3
#define LDMFD_SP_R4_5_PC 0x00101A34
#define LDR_R0_0_POP_R4_PC 0x0011BACC
#define POP_PC 0x001057C4
#define POP_R0_PC 0x0010C2FC
#define POP_R1_2_3_PC 0x00103DAC
#define POP_R3_PC 0x001050E8
#define POP_R4_5_6_PC 0x0010014C
#define POP_R4_5_6_7_8_9_10_11_12_PC 0x001065A8
#define STR_R1_0_POP_R4_PC 0x00106694
#define nn__gxlow__CTR__detail__GetInterruptReceiver 0x003D7C40
#if defined(SPIDER_9X_CN) //1.7567.CN
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD00
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA24
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x0023F808
#define SVC_0A_BX_LR 0x001041F8
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019B7E0
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022EA24
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x00167540
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001675C8
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B80B8
#define CALL_BX_LR 0x0023ECA0
#define CALL_BX_LR_2 0x001902B8
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C4EB0
#define POP_LR_PC 0x012FE78
#define POP_R0_1_2_3_4_7_PC 0x0019349B
#define POP_R1_PC 0x0022728C
#define POP_R2_3_PC 0x0014C8F4
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE74
#define MAGIC 0x0012FE60
#elif defined(SPIDER_9X_KR) //1.7567.KR
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BCD4
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012B9F8
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x002407D4
#define SVC_0A_BX_LR 0x001041F8
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CA80
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FA8C
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x00168718
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001687A0
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B9358
#define CALL_BX_LR 0x0023FC6C
#define CALL_BX_LR_2 0x00191554
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C5760
#define POP_LR_PC 0x0012FE4C
#define POP_R0_1_2_3_4_7_PC 0x0019473B
#define POP_R1_PC 0x0022825C
#define POP_R2_3_PC 0x0014D4E0
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE48
#define MAGIC 0x0012FE34
#elif defined(SPIDER_9X_TW) //1.7567.TW
#define HANDLE_PTR 0x003DA70C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012BD00
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BA24
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x00240868
#define SVC_0A_BX_LR 0x001041F8
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CAC8
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FB20
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x00168760
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x001687E8
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B93A0
#define CALL_BX_LR 0x0023FD00
#define CALL_BX_LR_2 0x0019159C
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C57F8
#define POP_LR_PC 0x0012FE78
#define POP_R0_1_2_3_4_7_PC 0x00194783
#define POP_R1_PC 0x002282D8
#define POP_R2_3_PC 0x0014D4E8
#define SP_LR_LDMFD_SP_LR_PC 0x0012FE74
#define MAGIC 0x0012FE60
#else //1.7567.JP/US/EU
#define DLPLAY_CODE_LOC (DLPLAY_CODE_LOC_VA-0x00100000+0x03F50000+0x14000000)
#define DLPLAY_HOOK_LOC (0x03FF3500+0x14000000)
#define HANDLE_PTR 0x003DA72C
#define GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC 0x0012C1E0
#define nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC 0x0012BF04
#define BLX_R5_LDMFD_SP_R4_5_6_7_8_PC 0x001B9308
#define CALL_BX_LR 0x0023FFE8
#define CALL_BX_LR_2 0x00191504
#define LDMFD_SP_R4_5_6_LR_BX_R12 0x002C5AE0
#define POP_LR_PC 0x0013035C
#define POP_R0_1_2_3_4_PC 0x0010B5B4
#define POP_R0_1_2_3_4_7_PC 0x001946EB
#define POP_R1_PC 0x00228AF4
#define POP_R2_3_PC 0x0014D598
#define POP_R2_3_4_PC 0x001007B4
#define POP_R4_PC 0x001050F0
#define SP_LR_LDMFD_SP_LR_PC 0x00130358
#define SVC_0A_BX_LR 0x001041F8
#define FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC 0x0019CA30
#define IFile_Open_LDMFD_SP_R4_5_6_7_8_PC 0x0022FE08
#define IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC 0x001686DC
#define IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC 0x00168764
#define MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR 0x00240B50
#define MAGIC 0x00130344
#define ROP_LOC 0x08B88400
// #define ROP_LOC 0x08CF2000
#endif
#else
#error ROP version not defined
#endif
#if defined(MSET_4X) || defined(MSET_4X_DG) || defined(MSET_6X)
#define CODE_ENTRY 0x00240000
#define BUFFER_LOC 0x14700000
#define rop_fs_mount(drive) .word POP_R0_PC, drive, FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC + 4, GARBAGE, GARBAGE, GARBAGE
#define rop_file_open(handle, filename, mode) .word POP_R0_PC, handle, POP_R1_2_3_PC, ROP_LOC+filename, mode, GARBAGE, IFile_Open + 4, GARBAGE, GARBAGE, GARBAGE, GARBAGE, POP_PC
#define rop_flush_data_cache(buffer, size) .word POP_R0_PC, HANDLE_PTR, POP_R1_2_3_PC, KPROCESS_HANDLE, buffer, size, GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC + 4, GARBAGE, GARBAGE, GARBAGE
#if defined(MSET_6X)
#define THIS 0x00287000
#define rop_file_read(handle, readcount, buffer, size) .word POP_R0_PC, handle, POP_R1_2_3_PC, readcount, buffer, size, IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC + 4, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE
#define rop_file_write(handle, writecount, buffer, size) .word POP_R1_2_3_PC, GARBAGE, POP_PC, GARBAGE, POP_R4_LR_BX_R2, GARBAGE, POP_PC, POP_R0_PC, handle, POP_R1_2_3_PC, writecount, buffer, size, IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC
#define rop_memcpy(dst, src, size) .word POP_R0_PC, dst, POP_R1_2_3_PC, src, size, GARBAGE, MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR + 4, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE
#define rop_sleep(ns) .word POP_R0_PC, ns, POP_R1_2_3_PC, 0, POP_PC, GARBAGE, POP_R4_LR_BX_R2, GARBAGE, POP_PC, SVC_0A_BX_LR
#else
#define THIS 0x00279000
#define rop_file_read(handle, readcount, buffer, size) .word POP_R0_R2_PC, handle, POP_PC, POP_R4_LR_BX_R2, GARBAGE, POP_PC, POP_R1_2_3_PC, readcount, buffer, size, IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC
#define rop_file_write(handle, writecount, buffer, size) .word POP_R0_R2_PC, handle, POP_PC, POP_R4_LR_BX_R2, GARBAGE, POP_PC, POP_R1_2_3_PC, writecount, buffer, size, IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC
#define rop_memcpy(dst, src, size) .word POP_R0_R2_PC, dst, POP_PC, POP_R4_LR_BX_R2, GARBAGE, POP_PC, POP_R1_2_3_PC, src, size, GARBAGE, MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR
#define rop_sleep(ns) .word POP_R0_R2_PC, ns, POP_PC, POP_R4_LR_BX_R2, GARBAGE, POP_PC, POP_R1_PC, 0, SVC_0A_BX_LR
#endif
#else //Spider
#define CODE_ENTRY 0x009D2000
#define THIS 0x0978CC00
#ifndef CODE_TARGET
#define CODE_TARGET 0x19592000
#endif
//#define THIS 0x08F10000
#ifndef ROP_LOC
#if (defined(SPIDER_42_CN) || defined(SPIDER_45_CN) || defined(SPIDER_5X_CN) || defined(SPIDER_9X_CN))
#define ROP_LOC 0x08CC0000
#else
#define ROP_LOC 0x08CD0000
#endif
#endif
#define BUFFER_LOC 0x18410000
#define rop_flush_data_cache(buffer, size) .word POP_LR_PC, POP_PC, POP_R0_PC, HANDLE_PTR, POP_R1_2_3_PC, KPROCESS_HANDLE, buffer, size, GSPGPU_FlushDataCache_LDMFD_SP_R4_5_6_PC
#define rop_fs_mount(drive) .word POP_LR_PC, POP_PC, POP_R0_PC, drive, FS_MOUNTSDMC_LDMFD_SP_R3_4_5_PC
#define rop_sleep(ns) .word POP_LR_PC, POP_PC, POP_R0_PC, ns, POP_R1_PC, 0, SVC_0A_BX_LR
#define rop_memcpy(dst, src, size) .word POP_LR_PC, POP_PC, POP_R0_PC, dst, POP_R1_2_3_PC, src, size, GARBAGE, MEMCPY_LDMFD_SP_R4_5_6_7_8_9_10_LR
#define rop_file_read(handle, readcount, buffer, size) .word POP_LR_PC, POP_PC, POP_R0_PC, handle, POP_R1_2_3_PC, readcount, buffer, size, IFile_Read_LDMFD_SP_R4_5_6_7_8_9_PC
#define rop_file_write(handle, writecount, buffer, size) .word POP_LR_PC, POP_PC, POP_R0_PC, handle, POP_R1_2_3_PC, writecount, buffer, size, IFile_Write_LDMFD_SP_R4_5_6_7_8_9_10_11_PC
#if defined(SPIDER_4X)
#define rop_file_open(handle, filename, mode) .word POP_LR_PC, POP_PC, POP_R0_PC, handle, POP_R1_2_3_PC, ROP_LOC+filename, mode, GARBAGE, IFile_Open_LDMFD_SP_R4_5_6_7_PC
#else
#define rop_file_open(handle, filename, mode) .word POP_LR_PC, POP_PC, POP_R0_PC, handle, POP_R1_2_3_PC, ROP_LOC+filename, mode, GARBAGE, IFile_Open_LDMFD_SP_R4_5_6_7_8_PC
#endif
#endif
#define JOIN(a,b) a##b
#define LABEL(a) JOIN(loc_, a)
#define LINE_LABEL LABEL(__LINE__)
#if defined(SPIDER_4X)
#define rop_gx_texture_copy(src, dst, size) LINE_LABEL: .word POP_R0_PC, nn__gxlow__CTR__detail__GetInterruptReceiver+0x58, POP_R1_PC, ROP_LOC+LINE_LABEL+0x14, nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_PC + 4, GX_SetTextureCopy, src, dst, (size+0xF)&~0xF, 0xFFFFFFFF, POP_R0_PC, 0x00000008
#else
#define rop_gx_texture_copy(src, dst, size) LINE_LABEL: .word POP_R0_PC, nn__gxlow__CTR__detail__GetInterruptReceiver+0x58, POP_R1_PC, ROP_LOC+LINE_LABEL+0x14, nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue_LDMFD_SP_R4_5_6_7_8_9_10_PC + 4, GX_SetTextureCopy, src, dst, (size+0xF)&~0xF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008
#endif
#define rop_jump(address) .word POP_R4_5_6_7_8_9_10_11_12_PC, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, GARBAGE, POP_PC, LDMFD_SP_R4_5_6_LR_BX_R12, GARBAGE, GARBAGE, GARBAGE, address-4, SP_LR_LDMFD_SP_LR_PC
#define rop_jump_arm .word CODE_ENTRY
#define rop_store(addr, val) .word POP_R0_PC, addr, POP_R1_PC, val, STR_R1_0_POP_R4_PC, GARBAGE

316
mset/source/appcompat.c Normal file
View File

@ -0,0 +1,316 @@
#include "appcompat.h"
compat_app_s* app = (compat_app_s *) APP_COMPAT;
#if defined(ENTRY_MSET)
compat_app_s mset_4x =
{
.memcpy = (void*) 0x001BFA60,
.GSPGPU_FlushDataCache = (void*) 0x001346C4,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x001AC924,
.svcControlMemory = (void*) 0x001C3E24,
.fopen = (void*) 0x001B82A8,
.fread = (void*) 0x001B3954,
.fwrite = (void*) 0x001B3B50,
.gpuHandle = (0x0027C580 + 0x58),
};
compat_app_s mset_6x =
{
.memcpy = (void*) 0x001C814C,
.GSPGPU_FlushDataCache = (void*) 0x00134A84,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x001B4E8C,
.svcControlMemory = (void*) 0x001CC63C,
.fopen = (void*) 0x001C08B4,
.fread = (void*) 0x001BC188,
.fwrite = (void*) 0x001BC380,
.gpuHandle = (0x0028A580 + 0x58),
};
#elif defined(ENTRY_SPIDER)
compat_app_s spider_4x =
{
.memcpy = (void*) 0x0029BF60,
.GSPGPU_FlushDataCache = (void*) 0x00344B84,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x002CF3EC,
.svcControlMemory = (void*) 0x002D6ADC,
.fopen = (void*) 0x0025B0A4,
.fread = (void*) 0x002FC8E4,
.fwrite = (void*) 0x00311D90,
.GX_SetTextureCopy = (void*) 0x002C62E4,
.svcSleepThread = (void*) 0x002A513C,
.gpuHandle = (0x003F54E8 + 0x58),
};
compat_app_s spider_5x =
{
.memcpy = (void*) 0x00240B58,
.GSPGPU_FlushDataCache = (void*) 0x001914FC,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BF4C,
.svcControlMemory = (void*) 0x001431C0,
.fopen = (void*) 0x0022FE44,
.fread = (void*) 0x001686C0,
.fwrite = (void*) 0x00168748,
.GX_SetTextureCopy = (void*) 0x0011DD80,
.svcSleepThread = (void*) 0x0010420C,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_9x =
{
.memcpy = (void*) 0x00240B50,
.GSPGPU_FlushDataCache = (void*) 0x00191504,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BF04,
.svcControlMemory = (void*) 0x001431A0,
.fopen = (void*) 0x0022FE08,
.fread = (void*) 0x001686DC,
.fwrite = (void*) 0x00168764,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x0023FFE8,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_42_cn =
{
.memcpy = (void*) 0x0023F048,
.GSPGPU_FlushDataCache = (void*) 0x00190118,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA40,
.svcControlMemory = (void*) 0x00142F64,
.fopen = (void*) 0x0022E334,
.fread = (void*) 0x001674BC,
.fwrite = (void*) 0x00167544,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x00104218,
.gpuHandle = (0x003D6C40 + 0x58),
};
compat_app_s spider_45_cn =
{
.memcpy = (void*) 0x0023EFA0,
.GSPGPU_FlushDataCache = (void*) 0x0018FC0C,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA54,
.svcControlMemory = (void*) 0x00142F58,
.fopen = (void*) 0x0022E2B0,
.fread = (void*) 0x00166FC8,
.fwrite = (void*) 0x00167050,
.GX_SetTextureCopy = (void*) 0x0011DD68,
.svcSleepThread = (void*) 0x0010420C,
.gpuHandle = (0x003D6C40 + 0x58),
};
compat_app_s spider_5x_cn =
{
.memcpy = (void*) 0x0023F80C,
.GSPGPU_FlushDataCache = (void*) 0x001902A8,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA6C,
.svcControlMemory = (void*) 0x00143110,
.fopen = (void*) 0x0022EA5C,
.fread = (void*) 0x0016751C,
.fwrite = (void*) 0x001675A4,
.GX_SetTextureCopy = (void*) 0x0011DD80,
.svcSleepThread = (void*) 0x0010420C,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_9x_cn =
{
.memcpy = (void*) 0x0023F808,
.GSPGPU_FlushDataCache = (void*) 0x001902B8,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA24,
.svcControlMemory = (void*) 0x001430F0,
.fopen = (void*) 0x0022EA24,
.fread = (void*) 0x00167540,
.fwrite = (void*) 0x001675C8,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x001041F8,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_4x_kr =
{
.memcpy = (void*) 0x0023FF90,
.GSPGPU_FlushDataCache = (void*) 0x00190D30,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA14,
.svcControlMemory = (void*) 0x00142FA0,
.fopen = (void*) 0x0022F284,
.fread = (void*) 0x001680F8,
.fwrite = (void*) 0x00168180,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x00104218,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_5x_kr =
{
.memcpy = (void*) 0x002407DC,
.GSPGPU_FlushDataCache = (void*) 0x0019154C,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA40,
.svcControlMemory = (void*) 0x00143108,
.fopen = (void*) 0x0022FAC8,
.fread = (void*) 0x001686FC,
.fwrite = (void*) 0x00168784,
.GX_SetTextureCopy = (void*) 0x0011DD80,
.svcSleepThread = (void*) 0x0010420C,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_9x_kr =
{
.memcpy = (void*) 0x002407D4,
.GSPGPU_FlushDataCache = (void*) 0x00191554,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012B9F8,
.svcControlMemory = (void*) 0x001430E8,
.fopen = (void*) 0x0022FA8C,
.fread = (void*) 0x00168718,
.fwrite = (void*) 0x001687A0,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x001041F8,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_4x_tw =
{
.memcpy = (void*) 0x0023FFE4,
.GSPGPU_FlushDataCache = (void*) 0x00190D34,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA40,
.svcControlMemory = (void*) 0x00142F64,
.fopen = (void*) 0x0022F2D8,
.fread = (void*) 0x001680FC,
.fwrite = (void*) 0x00168184,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x00104218,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_5x_tw =
{
.memcpy = (void*) 0x00240870,
.GSPGPU_FlushDataCache = (void*) 0x00191594,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA6C,
.svcControlMemory = (void*) 0x00143110,
.fopen = (void*) 0x0022FB5C,
.fread = (void*) 0x00168744,
.fwrite = (void*) 0x001687CC,
.GX_SetTextureCopy = (void*) 0x0011DD80,
.svcSleepThread = (void*) 0x0010420C,
.gpuHandle = (0x003D7C40 + 0x58),
};
compat_app_s spider_9x_tw =
{
.memcpy = (void*) 0x00240868,
.GSPGPU_FlushDataCache = (void*) 0x0019159C,
.nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue = (void*) 0x0012BA24,
.svcControlMemory = (void*) 0x001430F0,
.fopen = (void*) 0x0022FB20,
.fread = (void*) 0x00168760,
.fwrite = (void*) 0x001687E8,
.GX_SetTextureCopy = (void*) 0x0011DD48,
.svcSleepThread = (void*) 0x001041F8,
.gpuHandle = (0x003D7C40 + 0x58),
};
#endif
// Slow ass but safe memcpy
void _memcpy(void* dst, const void* src, uint32_t size)
{
char *destc = (char *) dst;
const char *srcc = (const char *) src;
for(uint32_t i = 0; i < size; i++)
{
destc[i] = srcc[i];
}
}
int set_app_offsets()
{
const compat_app_s *sapp = 0;
uint32_t app_spec = *(uint32_t *)0x0010000C;
switch(app_spec)
{
#if defined(ENTRY_MSET)
case 0xEB0312BF:
sapp = &mset_4x;
break;
case 0xEB0334CF:
sapp = &mset_6x;
break;
#elif defined(ENTRY_SPIDER)
case 0xEB0676B5:
sapp = &spider_4x;
break;
case 0xEB050B2A:
sapp = &spider_5x;
break;
case 0xEB050B28:
sapp = &spider_9x;
break;
case 0xEB050466:
sapp = &spider_42_cn;
break;
case 0xEB05043C:
sapp = &spider_45_cn;
break;
case 0xEB050657:
sapp = &spider_5x_cn;
break;
case 0xEB050656:
sapp = &spider_9x_cn;
break;
case 0xEB050838:
sapp = &spider_4x_kr;
break;
case 0xEB050A4B:
sapp = &spider_5x_kr;
break;
case 0xEB050A49:
sapp = &spider_9x_kr;
break;
case 0xEB05084D:
sapp = &spider_4x_tw;
break;
case 0xEB050A70:
sapp = &spider_5x_tw;
break;
case 0xEB050A6E:
sapp = &spider_9x_tw;
break;
#endif
}
if (sapp) {
_memcpy(app, sapp, sizeof(compat_app_s));
return 0;
}
else
return 1;
}

52
mset/source/appcompat.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef __appcompat_h__
#define __appcompat_h__
#include <stdint.h>
#include "launcher_path.h"
typedef struct compat_app_s
{
void (*memcpy)(void *dest, void *src, uint32_t len);
int (*GSPGPU_FlushDataCache)(void *address, uint32_t length);
void (*nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue)(void *arg1, void *arg2);
uint32_t (*svcControlMemory)(uint32_t *outaddr, uint32_t *addr0, uint32_t *addr1, uint32_t size, uint32_t operation, uint32_t permissions);
int (*fopen)(uint32_t (*handle)[], short unsigned int *path, int flags);
int (*fread)(uint32_t (*handle)[], uint32_t *read, void *buffer, uint32_t size);
int (*fwrite)(uint32_t (*handle)[], uint32_t *written, void *src, uint32_t size);
uint32_t gpuHandle;
#if defined(ENTRY_SPIDER)
int (*GX_SetTextureCopy)(void *input_buffer, void *output_buffer, uint32_t size, int in_x, int in_y, int out_x, int out_y, int flags);
int (*svcSleepThread)(unsigned long long nanoseconds);
#endif
} compat_app_s;
extern compat_app_s* app;
int set_app_offsets();
#if defined(ENTRY_MSET)
// The usable area for this app
#define APP_FCRAM_ADDR 0x14000000
#define APP_CFW_OFFSET 0x400000
#define APP_LAUNCHER_PATH (L"YS:/" LAUNCHER_PATH)
#elif defined(ENTRY_SPIDER)
// The usable area for this app
#define APP_FCRAM_ADDR 0x18400000
#define APP_CFW_OFFSET 0x4410000
#define APP_LAUNCHER_PATH (L"dmc:/" LAUNCHER_PATH)
#endif
// Locations in fcram
#define APP_CHECK_MEM (APP_FCRAM_ADDR + 0x1000)
#define APP_ARM11_BUFFER (APP_FCRAM_ADDR + 0x2000)
#define APP_MEM_HAX_MEM (APP_FCRAM_ADDR + 0x50000)
#define APP_COMPAT (APP_FCRAM_ADDR + 0x20000)
#define APP_FIRM_COMPAT (APP_FCRAM_ADDR + 0x20100)
#define ARM9_PAYLOAD_MAXSIZE 0x10000
#endif

10
mset/source/arm11_tools.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __arm11_tools_h__
#define __arm11_tools_h__
#include <stdint.h>
void invalidate_data_cache();
void invalidate_instruction_cache();
void asm_memcpy(void *dest, void *src, uint32_t length);
#endif

27
mset/source/arm11_tools.s Normal file
View File

@ -0,0 +1,27 @@
.global invalidate_data_cache
invalidate_data_cache:
mov r0, #0
mcr p15, 0, r0, c7, c14, 0 @ Clean and Invalidate Entire Data Cache
mcr p15, 0, r0, c7, c10, 4 @ Data Synchronization Barrier
bx lr
.global invalidate_instruction_cache
invalidate_instruction_cache:
mov r0, #0
mcr p15, 0, r0, c7, c5, 0
mcr p15, 0, r0, c7, c5, 4
mcr p15, 0, r0, c7, c5, 6
mcr p15, 0, r0, c7, c10, 4
bx lr
.global asm_memcpy
asm_memcpy:
add r2, r1
.memcpy_loop:
ldmia r1!, {r3}
stmia r0!, {r3}
cmp r1, r2
bcc .memcpy_loop
bx lr

45
mset/source/firmcompat.c Normal file
View File

@ -0,0 +1,45 @@
#include "firmcompat.h"
#include <stdint.h>
struct firmware_offsets *fw = (struct firmware_offsets *)APP_FIRM_COMPAT;
int set_firmware_offsets()
{
uint32_t kernel_version = *(uint32_t *)0x1FF80000;
// Offsets taken from bootstrap
switch (kernel_version) {
case 0x022E0000: // N3DS 9.0.0
fw->kernel_patch_address = 0xDFF8382F;
fw->reboot_patch_address = 0xDFFF4994;
fw->reboot_func_address = 0xFFF158F8;
fw->jump_table_address = 0xDFFF4C80;
fw->fcram_address = 0xE0000000;
fw->func_patch_address = 0xDFFE7A50;
fw->func_patch_return = 0xFFF28A58;
fw->pdn_regs = 0xFFFBE000;
fw->pxi_regs = 0xFFFC0000;
fw->gpu_regs = 0xFFFBC000;
break;
case 0x022C0600: // N3DS 8.0.0
fw->kernel_patch_address = 0xDFF8382F;
fw->reboot_patch_address = 0xDFFF4994;
fw->reboot_func_address = 0xFFF158F8;
fw->jump_table_address = 0xDFFF4C80;
fw->fcram_address = 0xE0000000;
fw->func_patch_address = 0xDFFE7A50;
fw->func_patch_return = 0xFFF28A58;
fw->pdn_regs = 0xFFFBE000;
fw->pxi_regs = 0xFFFC0000;
fw->gpu_regs = 0xFFFBC000;
break;
default:
return 1;
}
return 0;
}

24
mset/source/firmcompat.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef __firmcompat_h__
#define __firmcompat_h__
#include <stdint.h>
#include "appcompat.h"
struct firmware_offsets {
uint32_t kernel_patch_address;
uint32_t reboot_patch_address;
uint32_t reboot_func_address;
uint32_t jump_table_address;
uint32_t fcram_address;
uint32_t func_patch_address;
uint32_t func_patch_return;
uint32_t pdn_regs;
uint32_t pxi_regs;
uint32_t gpu_regs;
};
struct firmware_offsets *fw;
int set_firmware_offsets();
#endif

View File

@ -0,0 +1,72 @@
#include "firmlaunchax.h"
#include <stdint.h>
#include "firmcompat.h"
#include "appcompat.h"
#include "arm11_tools.h"
#include "jump_table.h"
void setup_gpu()
{
volatile uint32_t *top_left1 = (volatile uint32_t *)(fw->gpu_regs + 0x468);
volatile uint32_t *top_left2 = (volatile uint32_t *)(fw->gpu_regs + 0x46C);
volatile uint32_t *top_right1 = (volatile uint32_t *)(fw->gpu_regs + 0x494);
volatile uint32_t *top_right2 = (volatile uint32_t *)(fw->gpu_regs + 0x498);
volatile uint32_t *top_selected = (volatile uint32_t *)(fw->gpu_regs + 0x478);
volatile uint32_t *bottom1 = (volatile uint32_t *)(fw->gpu_regs + 0x568);
volatile uint32_t *bottom2 = (volatile uint32_t *)(fw->gpu_regs + 0x56C);
volatile uint32_t *bottom_selected = (volatile uint32_t *)(fw->gpu_regs + 0x578);
uint32_t *save = (uint32_t *)(fw->fcram_address + 0x3FFFE00);
if (*top_selected) {
save[0] = *top_left2;
save[1] = *top_right2;
} else {
save[0] = *top_left1;
save[1] = *top_right1;
}
if (*bottom_selected) {
save[2] = *bottom2;
} else {
save[2] = *bottom1;
}
}
void firmlaunch_arm9hax()
{
invalidate_data_cache();
invalidate_instruction_cache();
// Copy arm9 code
uint32_t code_offset = 0x3F00000;
asm_memcpy((void *)(fw->fcram_address + code_offset),
(void *)(fw->fcram_address + APP_CFW_OFFSET), ARM9_PAYLOAD_MAXSIZE);
// Prepare framebuffer info for arm9
setup_gpu();
// Copy the jump table
asm_memcpy((void *)fw->jump_table_address, &jump_table, (&jump_table_end - &jump_table + 1) * 4);
// Write firmware-specific offsets to the jump table
*(uint32_t *)(fw->jump_table_address +
(&jt_return - &jump_table) * 4) = fw->func_patch_return;
*(uint32_t *)(fw->jump_table_address +
(&jt_pdn_regs - &jump_table) * 4) = fw->pdn_regs;
*(uint32_t *)(fw->jump_table_address +
(&jt_pxi_regs - &jump_table) * 4) = fw->pxi_regs;
// Patch arm11 functions
*(uint32_t *)fw->func_patch_address = 0xE51FF004;
*(uint32_t *)(fw->func_patch_address + 4) = 0xFFFF0C80;
*(uint32_t *)fw->reboot_patch_address = 0xE51FF004;
*(uint32_t *)(fw->reboot_patch_address + 4) = 0x1FFF4C80+4;
invalidate_data_cache();
// Trigger reboot
((void (*)())fw->reboot_func_address)(0, 0, 2, 0);
while (1) {};
}

View File

@ -0,0 +1,6 @@
#ifndef __firmlaunchax_h__
#define __firmlaunchax_h__
void firmlaunch_arm9hax();
#endif

10
mset/source/jump_table.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __jump_table_h__
#define __jump_table_h__
extern void *jump_table __asm__("jump_table");
extern void *jump_table_end __asm__("jump_table_end");
extern void *jt_return __asm__("jt_return");
extern void *jt_pdn_regs __asm__("jt_pdn_regs");
extern void *jt_pxi_regs __asm__("jt_pxi_regs");
#endif

150
mset/source/jump_table.s Normal file
View File

@ -0,0 +1,150 @@
.arm
.align 4
.code 32
.text
.global jump_table
jump_table:
b func_patch_hook
b reboot_function
func_patch_hook:
push {r0-r12, lr}
mov r0, #0
bl pxi_send
bl pxi_sync
mov r0, #0x10000
bl pxi_send
bl pxi_recv
bl pxi_recv
bl pxi_recv
ldr r1, jt_pdn_regs
mov r0, #2
strb r0, [r1, #0x230]
mov r0, #0x10
bl busy_spin
mov r0, #0
strb r0, [r1, #0x230]
mov r0, #0x10
bl busy_spin
pop {r0-r12, lr}
ldr r0, =0x44836
str r0, [r1]
ldr pc, jt_return
reboot_function:
adr r0, arm11_reboot_hook
adr r1, arm11_reboot_hook_end
ldr r2, =0x1FFFFC00
mov r4, r2
bl copy_mem
bx r4
copy_mem:
sub r3, r1, r0
mov r1, r3,asr#2
cmp r1, #0
ble copy_mem_ret
movs r1, r3,lsl#29
sub r0, r0, #4
sub r1, r2, #4
bpl copy_mem_loc1
ldr r2, [r0,#4]!
str r2, [r1,#4]!
copy_mem_loc1:
movs r2, r3,asr#3
beq copy_mem_ret
copy_mem_loc2:
ldr r3, [r0,#4]
subs r2, r2, #1
str r3, [r1,#4]
ldr r3, [r0,#8]!
str r3, [r1,#8]!
bne copy_mem_loc2
copy_mem_ret:
bx lr
.pool
arm11_reboot_hook:
ldr r0, pxi_regs
ldr r1, pxi_command
str r1, [r0]
ldr r8, io_mem
ldr r9, arm9_payload
ldr r10, firm_header
wait_arm9_loop:
ldrb r0, [r8]
ands r0, r0, #1
bne wait_arm9_loop
str r9, [r10, #0xC]
mov r0, #0x1FFFFFF8
wait_arm11_loop:
ldr r1, [r0]
cmp r1, #0
beq wait_arm11_loop
bx r1
pxi_regs: .long 0x10163008
pxi_command: .long 0x44846
io_mem: .long 0x10140000
arm9_payload: .long 0x23F00000
firm_header: .long 0x24000000
arm11_reboot_hook_end:
.pool
busy_spin:
subs r0, #2
nop
bgt busy_spin
bx lr
pxi_send:
ldr r1, jt_pxi_regs
pxi_send_l1:
ldrh r2, [r1,#4]
tst r2, #2
bne pxi_send_l1
str r0, [r1,#8]
bx lr
pxi_sync:
ldr r0, jt_pxi_regs
ldrb r1, [r0,#3]
orr r1, #0x40
strb r1, [r0,#3]
bx lr
pxi_recv:
ldr r0, jt_pxi_regs
pxi_recv_l1:
ldrh r1, [r0,#4]
tst r1, #0x100
bne pxi_recv_l1
ldr r0, [r0,#0xC]
bx lr
.global jt_pdn_regs
jt_pdn_regs: .long 0
.global jt_pxi_regs
jt_pxi_regs: .long 0
.global jt_return
jt_return: .long 0
.global jump_table_end
jump_table_end:

View File

@ -0,0 +1,10 @@
#ifndef __launcher_path_h__
#define __launcher_path_h__
// This is a stupid file which just makes sure LAUNCHER_PATH is defined
// It should be defined externally, though.
#ifndef LAUNCHER_PATH
#define LAUNCHER_PATH "/reiNand.dat"
#endif
#endif

71
mset/source/main.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdint.h>
#include "firmcompat.h"
#include "appcompat.h"
#include "memchunkhax.h"
#include "firmlaunchax.h"
int load_file(char *dest, short unsigned int *path, uint32_t offset, uint32_t size)
{
uint32_t file_handle[8] = {0};
uint32_t bytes_read = 0;
int result = app->fopen(&file_handle, path, 1);
if (result != 0) {
return 1;
}
file_handle[1] = offset;
app->fread(&file_handle, &bytes_read, dest, size);
return 0;
}
__attribute__((naked))
void arm11_kernel_code()
{
__asm__ volatile ("clrex");
// Reboot and load our arm9 payload in arm9 kernel mode
firmlaunch_arm9hax();
// We should never return here
while (1) {};
}
void cls(){
uint8_t *const top_left_fb = (uint8_t *const)0x14184E60;
uint8_t *const top_right_fb = (uint8_t *const)0x14282160;
uint8_t *const top_left_fb2 = (uint8_t *const)0x141CB370;
uint8_t *const top_right_fb2 = (uint8_t *const)0x142C8670;
for(int i = 0; i < 0x00046500; ++i)
{
top_left_fb[i] = 0xFF;
top_right_fb[i] = 0xFF;
top_left_fb2[i] = 0xFF;
top_right_fb2[i] = 0xFF;
}
}
void main()
{
cls();
int result;
// Some offsets that differ per entry
result = set_app_offsets();
if (result != 0) return;
// Some offsets differ per firmware
result = set_firmware_offsets();
if (result != 0) return; // Unsupported firmware, bailing out.
// Load the arm9 payload to memory
// Spider has size restrictions to the Launcher, so we need to load the arm9
// payload separately.
result = load_file((char *)(0x14000000 + APP_CFW_OFFSET),
APP_LAUNCHER_PATH, 0x12000, ARM9_PAYLOAD_MAXSIZE);
if (result != 0) return; // The user is probably an idiot, bailing out.
// Now, we gain arm11 kernel mode
memchunk_arm11hax(arm11_kernel_code);
}

112
mset/source/memchunkhax.c Normal file
View File

@ -0,0 +1,112 @@
#include "memchunkhax.h"
#include <stddef.h>
#include <stdint.h>
#include "firmcompat.h"
#include "appcompat.h"
void gspwn_copy(void *dest, void *src, uint32_t length, int check, int check_offset)
{
// We'll use some memory to check the copy is being done right.
void *check_mem = (void *)APP_CHECK_MEM;
int *check_loc = (int *)(check_mem + check_offset);
while(*check_loc != check) {
app->memcpy(check_mem, check_mem, 0x10000);
app->GSPGPU_FlushDataCache(src, length);
uint32_t arr1[] = {4, (uint32_t)src, (uint32_t)dest, length,
0xFFFFFFFF, 0xFFFFFFFF, 8, 0};
app->nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue((void *)app->gpuHandle, arr1);
app->GSPGPU_FlushDataCache(check_mem, 0x10);
uint32_t arr2[] = {4, (uint32_t)dest, (uint32_t)check_mem, 0x10,
0xFFFFFFFF, 0xFFFFFFFF, 8, 0};
app->nn__gxlow__CTR__CmdReqQueueTx__TryEnqueue((void *)app->gpuHandle, arr2);
app->memcpy(check_mem, check_mem, 0x10000);
}
}
#if defined(ENTRY_MSET)
void build_nop_slide(uint32_t *dest, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++) {
dest[i] = 0xE1A00000; // ARM instruction: nop
}
dest[i - 1] = 0xE12FFF1E; // ARM instruction: bx lr
}
#endif
__attribute__((naked))
void corrupted_svcCreateThread(__attribute__((unused)) void (*func)())
{
__asm__ volatile ("svc 8");
}
void memchunk_arm11hax(void (*func)())
{
// I need some memory locations to use
uint32_t *mem_hax_mem = (uint32_t *)APP_MEM_HAX_MEM;
uint32_t *mem_hax_mem_free = (uint32_t *)((uint32_t)mem_hax_mem + 0x1000);
// There's not much documentation on this code.
// I've never studied the logic of it, so I can't describe it in more detail.
// Free some random chunk of memory
uint32_t tmp_addr;
app->svcControlMemory(&tmp_addr, mem_hax_mem_free, NULL, 0x1000, 1 /* MEMOP_FREE */, 0);
// arm11_buffer is the location that is copied *from* when using gspwn_copy
uint32_t *arm11_buffer = (uint32_t *)APP_ARM11_BUFFER;
arm11_buffer[0] = 1;
arm11_buffer[1] = fw->kernel_patch_address;
arm11_buffer[2] = 0;
arm11_buffer[3] = 0;
// Copy the arm11_buffer to the freed memory with gspwn
gspwn_copy(mem_hax_mem_free, arm11_buffer, 0x10, fw->kernel_patch_address, 4);
// Trigger kernel write
app->svcControlMemory(&tmp_addr, mem_hax_mem, NULL, 0x1000, 1 /* MEMOP_FREE */, 0);
// Tricks to clear the instruction cache
#if defined(ENTRY_MSET)
int slide_len = 0x1000;
// Build a NOP slide
build_nop_slide(arm11_buffer, slide_len);
// Copy the NOP slide
uint32_t app_code_offset = 0;
uint32_t kernel_version = *(uint32_t *)0x1FF80000;
if(kernel_version < 0x02230600) { // firm 4.x
app_code_offset = 0x03E6D000;
}
else { // > firm 4.x
app_code_offset = 0x7B00000;
}
gspwn_copy((void *)(0x14000000 + app_code_offset + 0x4000), arm11_buffer,
slide_len * 4, 0xE1A00000, 0);
// Run the NOP slide
((void (*)())0x104000)();
#elif defined(ENTRY_SPIDER)
// Fills the bottom buffer with a random pattern
void *src = (void *)0x18000000;
for (int i = 0; i < 3; i++) { // Do it 3 times to be safe
app->GSPGPU_FlushDataCache(src, 0x00038400);
app->GX_SetTextureCopy(src, (void *)0x1F48F000, 0x00038400, 0, 0, 0, 0, 8);
app->svcSleepThread(0x400000LL);
app->GSPGPU_FlushDataCache(src, 0x00038400);
app->GX_SetTextureCopy(src, (void *)0x1F4C7800, 0x00038400, 0, 0, 0, 0, 8);
app->svcSleepThread(0x400000LL);
}
#endif
// Get into arm11
corrupted_svcCreateThread(func);
}

View File

@ -0,0 +1,6 @@
#ifndef __memchunkhax_h__
#define __memchunkhax_h__
void memchunk_arm11hax(void (*func)());
#endif

View File

@ -0,0 +1,21 @@
FatFs Module Source Files R0.11
FILES
00readme.txt This file.
history.txt Revision history.
ffconf.h Configuration file for FatFs module.
ff.h Common include file for FatFs and application module.
ff.c FatFs module.
diskio.h Common include file for FatFs and disk I/O module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
integer.h Integer type definitions for FatFs.
option Optional external functions.
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
to control the target storage device.

View File

@ -0,0 +1,102 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "sdmmc/sdmmc.h"
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
__attribute__((unused))
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
__attribute__((unused))
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
sdmmc_sdcard_init();
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
if (sdmmc_sdcard_readsectors(sector, count, buff)) {
return RES_PARERR;
}
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
if (sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) {
return RES_PARERR;
}
return RES_OK;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber (0..) */
__attribute__((unused))
BYTE cmd, /* Control code */
__attribute__((unused))
void *buff /* Buffer to send/receive control data */
)
{
return RES_PARERR;
}
#endif

View File

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#define _USE_WRITE 1 /* 1: Enable disk_write function */
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,350 @@
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
/----------------------------------------------------------------------------/
/ FatFs module is a free software that opened under license policy of
/ following conditions.
/
/ Copyright (C) 2015, ChaN, all right reserved.
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/---------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 32020 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
#else /* Single partition configuration */
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
#endif
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode string */
#if !_USE_LFN
#error _LFN_UNICODE must be 0 at non-LFN cfg.
#endif
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != _MIN_SS
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
#endif
#if _FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
DWORD fsize; /* Sectors per FAT */
DWORD volbase; /* Volume start sector */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
BYTE flag; /* Status flags */
BYTE err; /* Abort flag (error code) */
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
DWORD fsize; /* File size */
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
#endif
#if _FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _FS_LOCK
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
#endif
#if _USE_LFN
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
#if _USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
#if _USE_LFN
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
FRESULT f_truncate (FIL* fp); /* Truncate file */
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !_FS_READONLY && !_FS_NORTC
DWORD get_fattime (void);
#endif
/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Fast seek feature */
#define CREATE_LINKMAP 0xFFFFFFFF
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _FATFS */

View File

@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
/---------------------------------------------------------------------------*/
#define _FFCONF 32020 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations
/---------------------------------------------------------------------------*/
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
/ bytes. Instead of private sector buffer eliminated from the file object,
/ common sector buffer in the file system object (FATFS) is used for the file
/ data transfer. */
#define _FS_READONLY 1
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 2
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
/ f_truncate() and f_rename() function are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 0
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read feature and related functions,
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
#define _USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 0
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable)
/ To enable it, also _FS_TINY need to be set to 1. */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define _CODE_PAGE 437
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 775 - Baltic
/ 850 - Multilingual Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 858 - Multilingual Latin 1 + Euro
/ 862 - Hebrew
/ 866 - Russian
/ 874 - Thai
/ 932 - Japanese Shift_JIS (DBCS)
/ 936 - Simplified Chinese GBK (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese Big5 (DBCS)
*/
#define _USE_LFN 2
#define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature.
/
/ 0: Disable LFN feature. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
/ to 1. This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 0
/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ When _LFN_UNICODE is 0, this option has no effect. */
#define _FS_RPATH 0
/* This option configures relative path feature.
/
/ 0: Disable relative path feature and remove related functions.
/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
/
/ Note that directory items read via f_readdir() are affected by this option. */
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID option switches string volume ID feature.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0
/* This option switches multi-partition feature. By default (0), each logical drive
/ number is bound to the same physical drive number and only an FAT volume found on
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
/ each logical drive number is bound to arbitrary physical drive and partition
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
#define _MIN_SS 512
#define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define _FS_NORTC 1
#define _NORTC_MON 2
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2015
/* The _FS_NORTC option switches timestamp feature. If the system does not have
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
/ to be added to the project to read current time form RTC. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
#define _FS_LOCK 0
/* The _FS_LOCK option switches file lock feature to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock feature. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock feature. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock feature is independent of re-entrancy. */
#define _FS_REENTRANT 0
#define _FS_TIMEOUT 1000
#define _SYNC_t HANDLE
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this feature.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.c. */
#define _WORD_ACCESS 0
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/
/ 0: Byte-by-byte access. Always compatible with all platforms.
/ 1: Word access. Do not choose this unless under both the following conditions.
/
/ * Address misaligned memory access is always allowed to ALL instructions.
/ * Byte order on the memory is little-endian.
/
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
/ Following table shows allowable settings of some processor types.
/
/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2
/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
/ AVR32 0 *1 RL78 0 *2 R32C 0 *2
/ PIC18 0/1 SH-2 0 *1 M16C 0/1
/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2
/ PIC32 0 *1 H8/300H 0 *1 8051 0/1
/
/ *1:Big-endian.
/ *2:Unaligned memory access is not supported.
/ *3:Some compilers generate LDM/STM for mem_cpy function.
*/

View File

@ -0,0 +1,180 @@
----------------------------------------------------------------------------
Revision history of FatFs module
----------------------------------------------------------------------------
R0.00 (February 26, 2006)
Prototype.
R0.01 (April 29, 2006)
First stable version.
R0.02 (June 01, 2006)
Added FAT12 support.
Removed unbuffered mode.
Fixed a problem on small (<32M) partition.
R0.02a (June 10, 2006)
Added a configuration option (_FS_MINIMUM).
R0.03 (September 22, 2006)
Added f_rename().
Changed option _FS_MINIMUM to _FS_MINIMIZE.
R0.03a (December 11, 2006)
Improved cluster scan algorithm to write files fast.
Fixed f_mkdir() creates incorrect directory on FAT32.
R0.04 (February 04, 2007)
Added f_mkfs().
Supported multiple drive system.
Changed some interfaces for multiple drive system.
Changed f_mountdrv() to f_mount().
R0.04a (April 01, 2007)
Supported multiple partitions on a physical drive.
Added a capability of extending file size to f_lseek().
Added minimization level 3.
Fixed an endian sensitive code in f_mkfs().
R0.04b (May 05, 2007)
Added a configuration option _USE_NTFLAG.
Added FSINFO support.
Fixed DBCS name can result FR_INVALID_NAME.
Fixed short seek (<= csize) collapses the file object.
R0.05 (August 25, 2007)
Changed arguments of f_read(), f_write() and f_mkfs().
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
Fixed f_mkdir() on FAT32 creates incorrect directory.
R0.05a (February 03, 2008)
Added f_truncate() and f_utime().
Fixed off by one error at FAT sub-type determination.
Fixed btr in f_read() can be mistruncated.
Fixed cached sector is not flushed when create and close without write.
R0.06 (April 01, 2008)
Added fputc(), fputs(), fprintf() and fgets().
Improved performance of f_lseek() on moving to the same or following cluster.
R0.07 (April 01, 2009)
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
Added long file name feature. (_USE_LFN)
Added multiple code page feature. (_CODE_PAGE)
Added re-entrancy for multitask operation. (_FS_REENTRANT)
Added auto cluster size selection to f_mkfs().
Added rewind option to f_readdir().
Changed result code of critical errors.
Renamed string functions to avoid name collision.
R0.07a (April 14, 2009)
Septemberarated out OS dependent code on reentrant cfg.
Added multiple sector size feature.
R0.07c (June 21, 2009)
Fixed f_unlink() can return FR_OK on error.
Fixed wrong cache control in f_lseek().
Added relative path feature.
Added f_chdir() and f_chdrive().
Added proper case conversion to extended character.
R0.07e (November 03, 2009)
Septemberarated out configuration options from ff.h to ffconf.h.
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
Fixed name matching error on the 13 character boundary.
Added a configuration option, _LFN_UNICODE.
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
R0.08 (May 15, 2010)
Added a memory configuration option. (_USE_LFN = 3)
Added file lock feature. (_FS_SHARE)
Added fast seek feature. (_USE_FASTSEEK)
Changed some types on the API, XCHAR->TCHAR.
Changed .fname in the FILINFO structure on Unicode cfg.
String functions support UTF-8 encoding files on Unicode cfg.
R0.08a (August 16, 2010)
Added f_getcwd(). (_FS_RPATH = 2)
Added sector erase feature. (_USE_ERASE)
Moved file lock semaphore table from fs object to the bss.
Fixed f_mkfs() creates wrong FAT32 volume.
R0.08b (January 15, 2011)
Fast seek feature is also applied to f_read() and f_write().
f_lseek() reports required table size on creating CLMP.
Extended format syntax of f_printf().
Ignores duplicated directory separators in given path name.
R0.09 (September 06, 2011)
f_mkfs() supports multiple partition to complete the multiple partition feature.
Added f_fdisk().
R0.09a (August 27, 2012)
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
Changed option name _FS_SHARE to _FS_LOCK.
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
R0.09b (January 24, 2013)
Added f_setlabel() and f_getlabel().
R0.10 (October 02, 2013)
Added selection of character encoding on the file. (_STRF_ENCODE)
Added f_closedir().
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
Added forced mount feature with changes of f_mount().
Improved behavior of volume auto detection.
Improved write throughput of f_puts() and f_printf().
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
Fixed f_write() can be truncated when the file size is close to 4GB.
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
R0.10a (January 15, 2014)
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
Added a configuration option of minimum sector size. (_MIN_SS)
2nd argument of f_rename() can have a drive number and it will be ignored.
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
Fixed f_close() invalidates the file object without volume lock.
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
R0.10b (May 19, 2014)
Fixed a hard error in the disk I/O layer can collapse the directory entry.
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
R0.10c (November 09, 2014)
Added a configuration option for the platforms without RTC. (_FS_NORTC)
Changed option name _USE_ERASE to _USE_TRIM.
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
Fixed a potential problem of FAT access that can appear on disk error.
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
R0.11 (February 09, 2015)
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)

View File

@ -0,0 +1,33 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef _FF_INTEGER
#define _FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
#else /* Embedded platform */
/* This type MUST be 8 bit */
typedef unsigned char BYTE;
/* These types MUST be 16 bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 16 bit or 32 bit */
typedef int INT;
typedef unsigned int UINT;
/* These types MUST be 32 bit */
typedef long LONG;
typedef unsigned long DWORD;
#endif
#endif

View File

@ -0,0 +1,39 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014, Normmatt
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 2, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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/.
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
#define vu8 volatile u8
#define vu16 volatile u16
#define vu32 volatile u32
#define vu64 volatile u64

View File

@ -0,0 +1,31 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014, Normmatt
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 2, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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/.
*/
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common.h"
void ioDelay(u32 us);

View File

@ -0,0 +1,37 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014, Normmatt
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 2, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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/.
*/
.arm
.global ioDelay
.type ioDelay STT_FUNC
@ioDelay ( u32 us )
ioDelay:
ldr r1, =0x18000000 @ VRAM
1:
@ Loop doing uncached reads from VRAM to make loop timing more reliable
ldr r2, [r1]
subs r0, #1
bgt 1b
bx lr

View File

@ -0,0 +1,487 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014, Normmatt
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 2, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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 "common.h"
#include "sdmmc.h"
#include "delay.h"
//Uncomment to enable 32bit fifo support?
//not currently working
//#define DATA32_SUPPORT
static struct mmcdevice handleNAND;
static struct mmcdevice handleSD;
mmcdevice *getMMCDevice(int drive)
{
if(drive==0) return &handleNAND;
return &handleSD;
}
int __attribute__((noinline)) geterror(struct mmcdevice *ctx)
{
//if(ctx->error == 0x4) return -1;
//else return 0;
return (ctx->error << 29) >> 31;
}
void __attribute__((noinline)) inittarget(struct mmcdevice *ctx)
{
sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber);
setckl(ctx->clk);
if (ctx->SDOPT == 0) {
sdmmc_mask16(REG_SDOPT, 0, 0x8000);
} else {
sdmmc_mask16(REG_SDOPT, 0x8000, 0);
}
}
void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
{
bool getSDRESP = (cmd << 15) >> 31;
u16 flags = (cmd << 15) >> 31;
const bool readdata = cmd & 0x20000;
const bool writedata = cmd & 0x40000;
if (readdata || writedata)
flags |= TMIO_STAT0_DATAEND;
ctx->error = 0;
while (sdmmc_read16(REG_SDSTATUS1) & TMIO_STAT1_CMD_BUSY); //mmc working?
sdmmc_write16(REG_SDIRMASK0,0);
sdmmc_write16(REG_SDIRMASK1,0);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
#ifdef DATA32_SUPPORT
if (readdata)
sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0x800);
if (writedata)
sdmmc_mask16(REG_SDDATACTL32, 0x800, 0x1000);
#else
sdmmc_mask16(REG_SDDATACTL32,0x1800,0);
#endif
sdmmc_write16(REG_SDCMDARG0,args &0xFFFF);
sdmmc_write16(REG_SDCMDARG1,args >> 16);
sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
u32 size = ctx->size;
u16 *dataPtr = (u16*)ctx->data;
#ifdef DATA32_SUPPORT
u32 *dataPtr32 = (u32*)ctx->data;
#endif
bool useBuf = ( NULL != dataPtr );
#ifdef DATA32_SUPPORT
bool useBuf32 = (useBuf && (0 == (3 & ((u32)dataPtr))));
#endif
u16 status0 = 0;
while(true) {
u16 status1 = sdmmc_read16(REG_SDSTATUS1);
if (status1 & TMIO_STAT1_RXRDY) {
if (readdata && useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_RXRDY);
if (size > 0x1FF) {
#ifdef DATA32_SUPPORT
if (useBuf32) {
for(int i = 0; i<0x200; i+=4)
*dataPtr32++ = sdmmc_read32(REG_SDFIFO32);
} else {
#endif
for(int i = 0; i<0x200; i+=2)
*dataPtr++ = sdmmc_read16(REG_SDFIFO);
#ifdef DATA32_SUPPORT
}
#endif
size -= 0x200;
}
}
}
if (status1 & TMIO_STAT1_TXRQ) {
if (writedata && useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ);
if (size > 0x1FF) {
#ifdef DATA32_SUPPORT
for (int i = 0; i<0x200; i+=4)
sdmmc_write32(REG_SDFIFO32,*dataPtr32++);
#else
for (int i = 0; i<0x200; i+=2)
sdmmc_write16(REG_SDFIFO,*dataPtr++);
#endif
size -= 0x200;
}
}
}
if (status1 & TMIO_MASK_GW) {
ctx->error |= 4;
break;
}
if (!(status1 & TMIO_STAT1_CMD_BUSY)) {
status0 = sdmmc_read16(REG_SDSTATUS0);
if (sdmmc_read16(REG_SDSTATUS0) & TMIO_STAT0_CMDRESPEND)
ctx->error |= 0x1;
if (status0 & TMIO_STAT0_DATAEND)
ctx->error |= 0x2;
if ((status0 & flags) == flags)
break;
}
}
ctx->stat0 = sdmmc_read16(REG_SDSTATUS0);
ctx->stat1 = sdmmc_read16(REG_SDSTATUS1);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
if (getSDRESP != 0) {
ctx->ret[0] = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16);
ctx->ret[1] = sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16);
ctx->ret[2] = sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16);
ctx->ret[3] = sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16);
}
}
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in)
{
if (handleSD.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleSD);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
handleSD.data = in;
handleSD.size = numsectors << 9;
sdmmc_send_command(&handleSD,0x52C19,sector_no);
return geterror(&handleSD);
}
int __attribute__((noinline)) sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out)
{
if (handleSD.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleSD);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
handleSD.data = out;
handleSD.size = numsectors << 9;
sdmmc_send_command(&handleSD,0x33C12,sector_no);
return geterror(&handleSD);
}
int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out)
{
if (handleNAND.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleNAND);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write32(REG_SDBLKCOUNT32,numsectors);
#else
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
#endif
handleNAND.data = out;
handleNAND.size = numsectors << 9;
sdmmc_send_command(&handleNAND,0x33C12,sector_no);
inittarget(&handleSD);
return geterror(&handleNAND);
}
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in) //experimental
{
if (handleNAND.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleNAND);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write32(REG_SDBLKCOUNT32,numsectors);
#else
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
#endif
handleNAND.data = in;
handleNAND.size = numsectors << 9;
sdmmc_send_command(&handleNAND,0x52C19,sector_no);
inittarget(&handleSD);
return geterror(&handleNAND);
}
u32 calcSDSize(u8* csd, int type)
{
u32 result = 0;
u8 temp = csd[0xE];
//int temp3 = type;
switch (type) {
case -1:
type = temp >> 6;
break;
case 0:
{
u32 temp = (csd[0x7] << 0x2 | csd[0x8] << 0xA | csd[0x6] >> 0x6 | (csd[0x9] & 0xF) << 0x10) & 0xFFF;
u32 temp2 = temp * (1 << (csd[0x9] & 0xF));
u32 retval = temp2 * (1 << (((csd[0x4] >> 7 | csd[0x5] << 1) & 7) + 2));
result = retval >> 9;
break;
}
case 1:
result = (((csd[0x7] & 0x3F) << 0x10 | csd[0x6] << 8 | csd[0x5]) + 1) << 0xA;
break;
default:
result = 0;
break;
}
return result;
}
void InitSD()
{
//NAND
handleNAND.isSDHC = 0;
handleNAND.SDOPT = 0;
handleNAND.res = 0;
handleNAND.initarg = 1;
handleNAND.clk = 0x80;
handleNAND.devicenumber = 1;
//SD
handleSD.isSDHC = 0;
handleSD.SDOPT = 0;
handleSD.res = 0;
handleSD.initarg = 0;
handleSD.clk = 0x80;
handleSD.devicenumber = 0;
//sdmmc_mask16(0x100,0x800,0);
//sdmmc_mask16(0x100,0x1000,0);
//sdmmc_mask16(0x100,0x0,0x402);
//sdmmc_mask16(0xD8,0x22,0x2);
//sdmmc_mask16(0x100,0x2,0);
//sdmmc_mask16(0xD8,0x22,0);
//sdmmc_write16(0x104,0);
//sdmmc_write16(0x108,1);
//sdmmc_mask16(REG_SDRESET,1,0); //not in new Version -- nintendo's code does this
//sdmmc_mask16(REG_SDRESET,0,1); //not in new Version -- nintendo's code does this
//sdmmc_mask16(0x20,0,0x31D);
//sdmmc_mask16(0x22,0,0x837F);
//sdmmc_mask16(0xFC,0,0xDB);
//sdmmc_mask16(0xFE,0,0xDB);
////sdmmc_write16(REG_SDCLKCTL,0x20);
////sdmmc_write16(REG_SDOPT,0x40EE);
////sdmmc_mask16(0x02,0x3,0);
//sdmmc_write16(REG_SDCLKCTL,0x40);
//sdmmc_write16(REG_SDOPT,0x40EB);
//sdmmc_mask16(0x02,0x3,0);
//sdmmc_write16(REG_SDBLKLEN,0x200);
//sdmmc_write16(REG_SDSTOP,0);
*(vu16*)0x10006100 &= 0xF7FFu; //SDDATACTL32
*(vu16*)0x10006100 &= 0xEFFFu; //SDDATACTL32
#ifdef DATA32_SUPPORT
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
#else
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
#endif
*(vu16*)0x100060D8 = (*(vu16*)0x100060D8 & 0xFFDD) | 2;
#ifdef DATA32_SUPPORT
*(vu16*)0x10006100 &= 0xFFFFu; //SDDATACTL32
*(vu16*)0x100060D8 &= 0xFFDFu; //SDDATACTL
*(vu16*)0x10006104 = 512; //SDBLKLEN32
#else
*(vu16*)0x10006100 &= 0xFFFDu; //SDDATACTL32
*(vu16*)0x100060D8 &= 0xFFDDu; //SDDATACTL
*(vu16*)0x10006104 = 0; //SDBLKLEN32
#endif
*(vu16*)0x10006108 = 1; //SDBLKCOUNT32
*(vu16*)0x100060E0 &= 0xFFFEu; //SDRESET
*(vu16*)0x100060E0 |= 1u; //SDRESET
*(vu16*)0x10006020 |= TMIO_MASK_ALL; //SDIR_MASK0
*(vu16*)0x10006022 |= TMIO_MASK_ALL>>16; //SDIR_MASK1
*(vu16*)0x100060FC |= 0xDBu; //SDCTL_RESERVED7
*(vu16*)0x100060FE |= 0xDBu; //SDCTL_RESERVED8
*(vu16*)0x10006002 &= 0xFFFCu; //SDPORTSEL
#ifdef DATA32_SUPPORT
*(vu16*)0x10006024 = 0x20;
*(vu16*)0x10006028 = 0x40EE;
#else
*(vu16*)0x10006024 = 0x40; //Nintendo sets this to 0x20
*(vu16*)0x10006028 = 0x40EB; //Nintendo sets this to 0x40EE
#endif
*(vu16*)0x10006002 &= 0xFFFCu; ////SDPORTSEL
*(vu16*)0x10006026 = 512; //SDBLKLEN
*(vu16*)0x10006008 = 0; //SDSTOP
inittarget(&handleSD);
}
int Nand_Init()
{
inittarget(&handleNAND);
ioDelay(0xF000);
sdmmc_send_command(&handleNAND,0,0);
do {
do {
sdmmc_send_command(&handleNAND,0x10701,0x100000);
} while ( !(handleNAND.error & 1) );
} while((handleNAND.ret[0] & 0x80000000) == 0);
sdmmc_send_command(&handleNAND,0x10602,0x0);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10403,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10609,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
handleNAND.total_size = calcSDSize((u8*)&handleNAND.ret[0],0);
handleNAND.clk = 1;
setckl(1);
sdmmc_send_command(&handleNAND,0x10407,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
handleNAND.SDOPT = 1;
sdmmc_send_command(&handleNAND,0x10506,0x3B70100);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10506,0x3B90100);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x1040D,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10410,0x200);
if (handleNAND.error & 0x4) return -1;
handleNAND.clk |= 0x200;
inittarget(&handleSD);
return 0;
}
int SD_Init()
{
inittarget(&handleSD);
//ioDelay(0x3E8);
ioDelay(0xF000);
sdmmc_send_command(&handleSD,0,0);
sdmmc_send_command(&handleSD,0x10408,0x1AA);
//u32 temp = (handleSD.ret[0] == 0x1AA) << 0x1E;
u32 temp = (handleSD.error & 0x1) << 0x1E;
//int count = 0;
u32 temp2 = 0;
do {
do {
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
sdmmc_send_command(&handleSD,0x10769,0x00FF8000 | temp);
temp2 = 1;
} while ( !(handleSD.error & 1) );
} while((handleSD.ret[0] & 0x80000000) == 0);
//do
//{
// sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
// sdmmc_send_command(&handleSD,0x10769,0x00FF8000 | temp);
//
//}
//while(!(handleSD.ret[0] & 0x80000000));
if(!((handleSD.ret[0] >> 30) & 1) || !temp)
temp2 = 0;
handleSD.isSDHC = temp2;
//handleSD.isSDHC = (handleSD.ret[0] & 0x40000000);
sdmmc_send_command(&handleSD,0x10602,0);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10403,0);
if (handleSD.error & 0x4) return -1;
handleSD.initarg = handleSD.ret[0] >> 0x10;
sdmmc_send_command(&handleSD,0x10609,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
handleSD.total_size = calcSDSize((u8*)&handleSD.ret[0],-1);
handleSD.clk = 1;
setckl(1);
sdmmc_send_command(&handleSD,0x10507,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
handleSD.SDOPT = 1;
sdmmc_send_command(&handleSD,0x10446,0x2);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x1040D,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10410,0x200);
if (handleSD.error & 0x4) return -1;
handleSD.clk |= 0x200;
return 0;
}
void sdmmc_sdcard_init()
{
InitSD();
Nand_Init();
SD_Init();
}

View File

@ -0,0 +1,191 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2014, Normmatt
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 2, as described below:
*
* This file is free software: you may copy, redistribute 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 file 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/.
*/
#pragma once
#include "common.h"
#define SDMMC_BASE 0x10006000u
#define REG_SDCMD 0x00
#define REG_SDPORTSEL 0x02
#define REG_SDCMDARG 0x04
#define REG_SDCMDARG0 0x04
#define REG_SDCMDARG1 0x06
#define REG_SDSTOP 0x08
#define REG_SDBLKCOUNT 0x0a
#define REG_SDRESP0 0x0c
#define REG_SDRESP1 0x0e
#define REG_SDRESP2 0x10
#define REG_SDRESP3 0x12
#define REG_SDRESP4 0x14
#define REG_SDRESP5 0x16
#define REG_SDRESP6 0x18
#define REG_SDRESP7 0x1a
#define REG_SDSTATUS0 0x1c
#define REG_SDSTATUS1 0x1e
#define REG_SDIRMASK0 0x20
#define REG_SDIRMASK1 0x22
#define REG_SDCLKCTL 0x24
#define REG_SDBLKLEN 0x26
#define REG_SDOPT 0x28
#define REG_SDFIFO 0x30
#define REG_SDDATACTL 0xd8
#define REG_SDRESET 0xe0
#define REG_SDPROTECTED 0xf6 //bit 0 determines if sd is protected or not?
#define REG_SDDATACTL32 0x100
#define REG_SDBLKLEN32 0x104
#define REG_SDBLKCOUNT32 0x108
#define REG_SDFIFO32 0x10C
#define REG_CLK_AND_WAIT_CTL 0x138
#define REG_RESET_SDIO 0x1e0
#define TMIO_STAT0_CMDRESPEND 0x0001
#define TMIO_STAT0_DATAEND 0x0004
#define TMIO_STAT0_CARD_REMOVE 0x0008
#define TMIO_STAT0_CARD_INSERT 0x0010
#define TMIO_STAT0_SIGSTATE 0x0020
#define TMIO_STAT0_WRPROTECT 0x0080
#define TMIO_STAT0_CARD_REMOVE_A 0x0100
#define TMIO_STAT0_CARD_INSERT_A 0x0200
#define TMIO_STAT0_SIGSTATE_A 0x0400
#define TMIO_STAT1_CMD_IDX_ERR 0x0001
#define TMIO_STAT1_CRCFAIL 0x0002
#define TMIO_STAT1_STOPBIT_ERR 0x0004
#define TMIO_STAT1_DATATIMEOUT 0x0008
#define TMIO_STAT1_RXOVERFLOW 0x0010
#define TMIO_STAT1_TXUNDERRUN 0x0020
#define TMIO_STAT1_CMDTIMEOUT 0x0040
#define TMIO_STAT1_RXRDY 0x0100
#define TMIO_STAT1_TXRQ 0x0200
#define TMIO_STAT1_ILL_FUNC 0x2000
#define TMIO_STAT1_CMD_BUSY 0x4000
#define TMIO_STAT1_ILL_ACCESS 0x8000
//Comes from TWLSDK mongoose.tef DWARF info
#define SDMC_NORMAL 0x00000000
#define SDMC_ERR_COMMAND 0x00000001
#define SDMC_ERR_CRC 0x00000002
#define SDMC_ERR_END 0x00000004
#define SDMC_ERR_TIMEOUT 0x00000008
#define SDMC_ERR_FIFO_OVF 0x00000010
#define SDMC_ERR_FIFO_UDF 0x00000020
#define SDMC_ERR_WP 0x00000040
#define SDMC_ERR_ABORT 0x00000080
#define SDMC_ERR_FPGA_TIMEOUT 0x00000100
#define SDMC_ERR_PARAM 0x00000200
#define SDMC_ERR_R1_STATUS 0x00000800
#define SDMC_ERR_NUM_WR_SECTORS 0x00001000
#define SDMC_ERR_RESET 0x00002000
#define SDMC_ERR_ILA 0x00004000
#define SDMC_ERR_INFO_DETECT 0x00008000
#define SDMC_STAT_ERR_UNKNOWN 0x00080000
#define SDMC_STAT_ERR_CC 0x00100000
#define SDMC_STAT_ERR_ECC_FAILED 0x00200000
#define SDMC_STAT_ERR_CRC 0x00800000
#define SDMC_STAT_ERR_OTHER 0xf9c70008
#define TMIO_MASK_ALL 0x837f031d
#define TMIO_MASK_GW (TMIO_STAT1_ILL_ACCESS | TMIO_STAT1_CMDTIMEOUT | TMIO_STAT1_TXUNDERRUN | TMIO_STAT1_RXOVERFLOW | \
TMIO_STAT1_DATATIMEOUT | TMIO_STAT1_STOPBIT_ERR | TMIO_STAT1_CRCFAIL | TMIO_STAT1_CMD_IDX_ERR)
#define TMIO_MASK_READOP (TMIO_STAT1_RXRDY | TMIO_STAT1_DATAEND)
#define TMIO_MASK_WRITEOP (TMIO_STAT1_TXRQ | TMIO_STAT1_DATAEND)
typedef struct mmcdevice {
u8* data;
u32 size;
u32 error;
u16 stat0;
u16 stat1;
u32 ret[4];
u32 initarg;
u32 isSDHC;
u32 clk;
u32 SDOPT;
u32 devicenumber;
u32 total_size; //size in sectors of the device
u32 res;
} mmcdevice;
/*int sdmmc_sdcard_init();
void sdmmc_sdcard_readsector(uint32_t sector_no, void *out);
void sdmmc_sdcard_readsectors(uint32_t sector_no, uint32_t numsectors, void *out);
void sdmmc_sdcard_writesector(uint32_t sector_no, void *in);
void sdmmc_sdcard_writesectors(uint32_t sector_no, uint32_t numsectors, void *in);
void sdmmc_blktransferinit();*/
void sdmmc_sdcard_init();
int sdmmc_sdcard_readsector(u32 sector_no, u8 *out);
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_sdcard_writesector(u32 sector_no, u8 *in);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in);
mmcdevice *getMMCDevice(int drive);
void InitSDMMC();
int Nand_Init();
int SD_Init();
static inline u16 sdmmc_read16(u16 reg) {
return *(vu16*)(SDMMC_BASE + reg);
}
static inline void sdmmc_write16(u16 reg, u16 val) {
*(vu16*)(SDMMC_BASE + reg) = val;
}
static inline u32 sdmmc_read32(u16 reg) {
return *(vu32*)(SDMMC_BASE + reg);
}
static inline void sdmmc_write32(u16 reg, u32 val) {
*(vu32*)(SDMMC_BASE + reg) = val;
}
static inline void sdmmc_mask16(u16 reg, const u16 clear, const u16 set) {
u16 val = sdmmc_read16(reg);
val &= ~clear;
val |= set;
sdmmc_write16(reg, val);
}
static inline void setckl(u32 data)
{
sdmmc_mask16(REG_SDCLKCTL, 0x100, 0);
sdmmc_mask16(REG_SDCLKCTL, 0x2FF, data & 0x2FF);
sdmmc_mask16(REG_SDCLKCTL, 0x0, 0x100);
}

View File

@ -0,0 +1,72 @@
#include <stdint.h>
#include <stddef.h>
#include "fatfs/ff.h"
#include "fatfs/sdmmc/sdmmc.h"
#include "../launcher_path.h"
void *payload_loc = (void *)0x08000000;
unsigned int payload_offset = 0x22000;
unsigned int payload_size = 0x50000;
// This is where the loader writes the framebuffer offsets
struct framebuffers {
uint32_t *top_left;
uint32_t *top_right;
uint32_t *bottom;
} *framebuffers = (struct framebuffers *)0x23FFFE00;
#define screen_top_width 400
#define screen_top_height 240
#define screen_bottom_width 340
#define screen_bottom_height 240
#define screen_top_size (screen_top_width * screen_top_height * 3)
#define screen_bottom_size (screen_bottom_width * screen_bottom_height * 3)
void memset32(void *dest, uint32_t filler, uint32_t size)
{
uint32_t *dest32 = (uint32_t *)dest;
for (uint32_t i = 0; i < size / 4; i++) {
dest32[i] = filler;
}
}
void clear_screens() {
memset32(framebuffers->top_left, 0, screen_top_size);
memset32(framebuffers->top_right, 0, screen_top_size);
memset32(framebuffers->bottom, 0, screen_bottom_size);
}
// This is supposed to be a small-ish payload that loads a bigger payload.
// This exists because some payloads are too big to be loaded in the memory of some apps.
void main()
{
FATFS fs;
FIL handle;
unsigned int bytes_read;
// Mount the SD card
if (f_mount(&fs, "0:", 1) != FR_OK) return;
// Load the payload
if (f_open(&handle, "/" LAUNCHER_PATH, FA_READ) != FR_OK) return;
if (f_lseek(&handle, payload_offset) != FR_OK) return;
if (f_read(&handle, payload_loc, payload_size, &bytes_read) != FR_OK) return;
if (f_close(&handle) != FR_OK) return;
// Unmount the SD card
if (f_mount(NULL, "0:", 1) != FR_OK) return;
// This is mostly to adhere to the gateway "standard",
// so existing gateway payloads don't have to be modified.
// Write the framebuffer offsets to the places where gateway expects them
*(uint32_t **)0x080FFFC0 = framebuffers->top_left;
*(uint32_t **)0x080FFFC4 = framebuffers->top_right;
*(uint32_t **)0x080FFFD4 = framebuffers->bottom;
*(uint32_t *)0x080FFFD8 = 0; // Select top framebuffer?
// Loaded correctly. The rest is up to the payload.
clear_screens();
// Jump to the payload, right behind the interrupt vector table.
((void (*)())(payload_loc + 0x30))();
}

View File

@ -0,0 +1,48 @@
.section .text.start
.align 4
.global _start
_start:
@ Change the stack pointer
mov sp, #0x27000000
@ Sets MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k
ldr r1, =0x01FF801D @ 01ff8000 32k
ldr r2, =0x08000027 @ 08000000 1M
ldr r3, =0x10000021 @ 10000000 128k
ldr r4, =0x10100025 @ 10100000 512k
ldr r5, =0x20000035 @ 20000000 128M
ldr r6, =0x2800801B @ 28008000 16k
ldr r7, =0x1800002D @ 18000000 8M
ldr r8, =0x33333336
ldr r9, =0x60600666
mov r10, #0x25
mov r11, #0x25
mov r12, #0x25
mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0
mcr p15, 0, r3, c6, c3, 0
mcr p15, 0, r4, c6, c4, 0
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
mcr p15, 0, r8, c5, c0, 2 @ Enable data r/w for all regions
mcr p15, 0, r9, c5, c0, 3 @ Enable inst read for 0, 1, 2, 5, 7
mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5
mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5
mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5
@ Enables all the settings we specified above
ldr r0, =0x5307D
mcr p15, 0, r0, c1, c0, 0 @ cp15 ctl register enable mpu, enable cache and use alt vector table
@ Undocumented: Fixes mounting of SDMC
ldr r0, =0x10000020
mov r1, #0x340
str r1, [r0]
bl main
.die:
b .die

5
mset/source/start.s Normal file
View File

@ -0,0 +1,5 @@
.section .text.start
.align 4
.global _start
_start:
b main

40
source/emunand.c Normal file
View File

@ -0,0 +1,40 @@
/*
* emunand.c
* by Reisyukaku
*/
#include "emunand.h"
#include "fatfs/ff.h"
#include "fatfs/sdmmc/sdmmc.h"
typedef struct emunand {
u32 offset;
u32 header;
const char* name;
} emunand;
emunand emunands[] = {
{.offset = 1, .header = 1, .name = "redNAND"},
{.offset = 0, .header = 0x1D7800, .name = "Toshiba GW/MT"},
{.offset = 0, .header = 0x1DD000, .name = "Samsung GW/MT"},
{.offset = 0, .header = 0x26C000, .name = "Samsung N3DS GW"},
{.offset = 0, .header = 0x3B0000, .name = "Unknown N3DS GW"},
{.offset = 0, .header = 0, .name = 0},
};
static u8 *temp = (u8 *)0x24300000;
u8 getEmunand(u32 *off, u32 *head){
u8 ret = 0;
for(int i = 0; emunands[i].name; i++){
if (sdmmc_sdcard_readsectors(emunands[i].header, 1, temp) == 0) {
if (*(u32 *)(temp + 0x100) == NCSD_MAGIC) {
*off = (u32)&emunands[i].offset;
*head = (u32)&emunands[i].header;
ret = 1;
break;
}
}
}
return ret;
}

15
source/emunand.h Normal file
View File

@ -0,0 +1,15 @@
/*
* emunand.h
* by Reisyukaku
*/
#ifndef EMU_INC
#define EMU_INC
#include "types.h"
#define NCSD_MAGIC (0x4453434E)
u8 getEmunand(u32 *off, u32 *head);
#endif

21
source/fatfs/00readme.txt Normal file
View File

@ -0,0 +1,21 @@
FatFs Module Source Files R0.11
FILES
00readme.txt This file.
history.txt Revision history.
ffconf.h Configuration file for FatFs module.
ff.h Common include file for FatFs and application module.
ff.c FatFs module.
diskio.h Common include file for FatFs and disk I/O module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
integer.h Integer type definitions for FatFs.
option Optional external functions.
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
to control the target storage device.

102
source/fatfs/diskio.c Normal file
View File

@ -0,0 +1,102 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "sdmmc/sdmmc.h"
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
__attribute__((unused))
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
__attribute__((unused))
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
sdmmc_sdcard_init();
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
if (sdmmc_sdcard_readsectors(sector, count, buff)) {
return RES_PARERR;
}
return RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
if (sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) {
return RES_PARERR;
}
return RES_OK;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
__attribute__((unused))
BYTE pdrv, /* Physical drive nmuber (0..) */
__attribute__((unused))
BYTE cmd, /* Control code */
__attribute__((unused))
void *buff /* Buffer to send/receive control data */
)
{
return RES_PARERR;
}
#endif

80
source/fatfs/diskio.h Normal file
View File

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#define _USE_WRITE 1 /* 1: Enable disk_write function */
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

4694
source/fatfs/ff.c Normal file

File diff suppressed because it is too large Load Diff

350
source/fatfs/ff.h Normal file
View File

@ -0,0 +1,350 @@
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module include R0.11 (C)ChaN, 2015
/----------------------------------------------------------------------------/
/ FatFs module is a free software that opened under license policy of
/ following conditions.
/
/ Copyright (C) 2015, ChaN, all right reserved.
/
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/---------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 32020 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
#else /* Single partition configuration */
#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */
#define LD2PT(vol) 0 /* Find first valid partition or in SFD */
#endif
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode string */
#if !_USE_LFN
#error _LFN_UNICODE must be 0 at non-LFN cfg.
#endif
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != _MIN_SS
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
#endif
#if _FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */
DWORD fsize; /* Sectors per FAT */
DWORD volbase; /* Volume start sector */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
BYTE flag; /* Status flags */
BYTE err; /* Abort flag (error code) */
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
DWORD fsize; /* File size */
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
#endif
#if _FS_LOCK
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _FS_LOCK
UINT lockid; /* File lock ID (index of file semaphore table Files[]) */
#endif
#if _USE_LFN
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
#if _USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
#if _USE_LFN
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */
FRESULT f_truncate (FIL* fp); /* Truncate file */
FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of the file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->fsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !_FS_READONLY && !_FS_NORTC
DWORD get_fattime (void);
#endif
/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Fast seek feature */
#define CREATE_LINKMAP 0xFFFFFFFF
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _FATFS */

271
source/fatfs/ffconf.h Normal file
View File

@ -0,0 +1,271 @@
/*---------------------------------------------------------------------------/
/ FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015
/---------------------------------------------------------------------------*/
#define _FFCONF 32020 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Functions and Buffer Configurations
/---------------------------------------------------------------------------*/
#define _FS_TINY 0
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
/ bytes. Instead of private sector buffer eliminated from the file object,
/ common sector buffer in the file system object (FATFS) is used for the file
/ data transfer. */
#define _FS_READONLY 0
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 1
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
/ f_truncate() and f_rename() function are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 0
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read feature and related functions,
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
#define _USE_MKFS 0
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 0
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable)
/ To enable it, also _FS_TINY need to be set to 1. */
/*---------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/---------------------------------------------------------------------------*/
#define _CODE_PAGE 437
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 775 - Baltic
/ 850 - Multilingual Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 858 - Multilingual Latin 1 + Euro
/ 862 - Hebrew
/ 866 - Russian
/ 874 - Thai
/ 932 - Japanese Shift_JIS (DBCS)
/ 936 - Simplified Chinese GBK (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese Big5 (DBCS)
*/
#define _USE_LFN 2
#define _MAX_LFN 255
/* The _USE_LFN option switches the LFN feature.
/
/ 0: Disable LFN feature. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
/ to 1. This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 0
/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ When _LFN_UNICODE is 0, this option has no effect. */
#define _FS_RPATH 0
/* This option configures relative path feature.
/
/ 0: Disable relative path feature and remove related functions.
/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
/
/ Note that directory items read via f_readdir() are affected by this option. */
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/---------------------------------------------------------------------------*/
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID option switches string volume ID feature.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
#define _MULTI_PARTITION 0
/* This option switches multi-partition feature. By default (0), each logical drive
/ number is bound to the same physical drive number and only an FAT volume found on
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
/ each logical drive number is bound to arbitrary physical drive and partition
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
#define _MIN_SS 512
#define _MAX_SS 512
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/---------------------------------------------------------------------------*/
#define _FS_NORTC 1
#define _NORTC_MON 2
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2015
/* The _FS_NORTC option switches timestamp feature. If the system does not have
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
/ to be added to the project to read current time form RTC. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
#define _FS_LOCK 0
/* The _FS_LOCK option switches file lock feature to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock feature. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock feature. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock feature is independent of re-entrancy. */
#define _FS_REENTRANT 0
#define _FS_TIMEOUT 1000
#define _SYNC_t HANDLE
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this feature.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.c. */
#define _WORD_ACCESS 0
/* The _WORD_ACCESS option is an only platform dependent option. It defines
/ which access method is used to the word data on the FAT volume.
/
/ 0: Byte-by-byte access. Always compatible with all platforms.
/ 1: Word access. Do not choose this unless under both the following conditions.
/
/ * Address misaligned memory access is always allowed to ALL instructions.
/ * Byte order on the memory is little-endian.
/
/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
/ Following table shows allowable settings of some processor types.
/
/ ARM7TDMI 0 *2 ColdFire 0 *1 V850E 0 *2
/ Cortex-M3 0 *3 Z80 0/1 V850ES 0/1
/ Cortex-M0 0 *2 x86 0/1 TLCS-870 0/1
/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
/ AVR32 0 *1 RL78 0 *2 R32C 0 *2
/ PIC18 0/1 SH-2 0 *1 M16C 0/1
/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2
/ PIC32 0 *1 H8/300H 0 *1 8051 0/1
/
/ *1:Big-endian.
/ *2:Unaligned memory access is not supported.
/ *3:Some compilers generate LDM/STM for mem_cpy function.
*/

180
source/fatfs/history.txt Normal file
View File

@ -0,0 +1,180 @@
----------------------------------------------------------------------------
Revision history of FatFs module
----------------------------------------------------------------------------
R0.00 (February 26, 2006)
Prototype.
R0.01 (April 29, 2006)
First stable version.
R0.02 (June 01, 2006)
Added FAT12 support.
Removed unbuffered mode.
Fixed a problem on small (<32M) partition.
R0.02a (June 10, 2006)
Added a configuration option (_FS_MINIMUM).
R0.03 (September 22, 2006)
Added f_rename().
Changed option _FS_MINIMUM to _FS_MINIMIZE.
R0.03a (December 11, 2006)
Improved cluster scan algorithm to write files fast.
Fixed f_mkdir() creates incorrect directory on FAT32.
R0.04 (February 04, 2007)
Added f_mkfs().
Supported multiple drive system.
Changed some interfaces for multiple drive system.
Changed f_mountdrv() to f_mount().
R0.04a (April 01, 2007)
Supported multiple partitions on a physical drive.
Added a capability of extending file size to f_lseek().
Added minimization level 3.
Fixed an endian sensitive code in f_mkfs().
R0.04b (May 05, 2007)
Added a configuration option _USE_NTFLAG.
Added FSINFO support.
Fixed DBCS name can result FR_INVALID_NAME.
Fixed short seek (<= csize) collapses the file object.
R0.05 (August 25, 2007)
Changed arguments of f_read(), f_write() and f_mkfs().
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
Fixed f_mkdir() on FAT32 creates incorrect directory.
R0.05a (February 03, 2008)
Added f_truncate() and f_utime().
Fixed off by one error at FAT sub-type determination.
Fixed btr in f_read() can be mistruncated.
Fixed cached sector is not flushed when create and close without write.
R0.06 (April 01, 2008)
Added fputc(), fputs(), fprintf() and fgets().
Improved performance of f_lseek() on moving to the same or following cluster.
R0.07 (April 01, 2009)
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
Added long file name feature. (_USE_LFN)
Added multiple code page feature. (_CODE_PAGE)
Added re-entrancy for multitask operation. (_FS_REENTRANT)
Added auto cluster size selection to f_mkfs().
Added rewind option to f_readdir().
Changed result code of critical errors.
Renamed string functions to avoid name collision.
R0.07a (April 14, 2009)
Septemberarated out OS dependent code on reentrant cfg.
Added multiple sector size feature.
R0.07c (June 21, 2009)
Fixed f_unlink() can return FR_OK on error.
Fixed wrong cache control in f_lseek().
Added relative path feature.
Added f_chdir() and f_chdrive().
Added proper case conversion to extended character.
R0.07e (November 03, 2009)
Septemberarated out configuration options from ff.h to ffconf.h.
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
Fixed name matching error on the 13 character boundary.
Added a configuration option, _LFN_UNICODE.
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
R0.08 (May 15, 2010)
Added a memory configuration option. (_USE_LFN = 3)
Added file lock feature. (_FS_SHARE)
Added fast seek feature. (_USE_FASTSEEK)
Changed some types on the API, XCHAR->TCHAR.
Changed .fname in the FILINFO structure on Unicode cfg.
String functions support UTF-8 encoding files on Unicode cfg.
R0.08a (August 16, 2010)
Added f_getcwd(). (_FS_RPATH = 2)
Added sector erase feature. (_USE_ERASE)
Moved file lock semaphore table from fs object to the bss.
Fixed f_mkfs() creates wrong FAT32 volume.
R0.08b (January 15, 2011)
Fast seek feature is also applied to f_read() and f_write().
f_lseek() reports required table size on creating CLMP.
Extended format syntax of f_printf().
Ignores duplicated directory separators in given path name.
R0.09 (September 06, 2011)
f_mkfs() supports multiple partition to complete the multiple partition feature.
Added f_fdisk().
R0.09a (August 27, 2012)
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
Changed option name _FS_SHARE to _FS_LOCK.
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
R0.09b (January 24, 2013)
Added f_setlabel() and f_getlabel().
R0.10 (October 02, 2013)
Added selection of character encoding on the file. (_STRF_ENCODE)
Added f_closedir().
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
Added forced mount feature with changes of f_mount().
Improved behavior of volume auto detection.
Improved write throughput of f_puts() and f_printf().
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
Fixed f_write() can be truncated when the file size is close to 4GB.
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code.
R0.10a (January 15, 2014)
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
Added a configuration option of minimum sector size. (_MIN_SS)
2nd argument of f_rename() can have a drive number and it will be ignored.
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
Fixed f_close() invalidates the file object without volume lock.
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
R0.10b (May 19, 2014)
Fixed a hard error in the disk I/O layer can collapse the directory entry.
Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. (appeared at R0.07)
R0.10c (November 09, 2014)
Added a configuration option for the platforms without RTC. (_FS_NORTC)
Changed option name _USE_ERASE to _USE_TRIM.
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
Fixed a potential problem of FAT access that can appear on disk error.
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
R0.11 (February 09, 2015)
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)

33
source/fatfs/integer.h Normal file
View File

@ -0,0 +1,33 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef _FF_INTEGER
#define _FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
#else /* Embedded platform */
/* This type MUST be 8 bit */
typedef unsigned char BYTE;
/* These types MUST be 16 bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 16 bit or 32 bit */
typedef int INT;
typedef unsigned int UINT;
/* These types MUST be 32 bit */
typedef long LONG;
typedef unsigned long DWORD;
#endif
#endif

View File

@ -0,0 +1,151 @@
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2014 */
/*------------------------------------------------------------------------*/
#include "../ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
BYTE vol, /* Corresponding logical drive being processed */
_SYNC_t *sobj /* Pointer to return the created sync object */
)
{
int ret;
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
ret = (int)(*sobj != INVALID_HANDLE_VALUE);
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
// ret = 1; /* The initial value of the semaphore must be 1. */
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
// ret = (int)(*sobj != NULL);
return ret;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
int ret;
ret = CloseHandle(sobj); /* Win32 */
// ret = 1; /* uITRON (nothing to do) */
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// vSemaphoreDelete(sobj); /* FreeRTOS */
// ret = 1;
return ret;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
_SYNC_t sobj /* Sync object to wait */
)
{
int ret;
ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
return ret;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
_SYNC_t sobj /* Sync object to be signaled */
)
{
ReleaseMutex(sobj); /* Win32 */
// sig_sem(sobj); /* uITRON */
// OSMutexPost(sobj); /* uC/OS-II */
// xSemaphoreGive(sobj); /* FreeRTOS */
}
#endif
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
free(mblock); /* Discard the memory block with POSIX API */
}
#endif

View File

@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
#define vu8 volatile u8
#define vu16 volatile u16
#define vu32 volatile u32
#define vu64 volatile u64

View File

@ -0,0 +1,9 @@
// Copyright 2014 Normmatt
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common.h"
void ioDelay(u32 us);

View File

@ -0,0 +1,17 @@
// Copyright 2014 Normmatt
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
.arm
.global ioDelay
.type ioDelay STT_FUNC
@ioDelay ( u32 us )
ioDelay:
ldr r1, =0x18000000 @ VRAM
1:
@ Loop doing uncached reads from VRAM to make loop timing more reliable
ldr r2, [r1]
subs r0, #1
bgt 1b
bx lr

467
source/fatfs/sdmmc/sdmmc.c Normal file
View File

@ -0,0 +1,467 @@
// Copyright 2014 Normmatt
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common.h"
#include "sdmmc.h"
#include "delay.h"
//Uncomment to enable 32bit fifo support?
//not currently working
//#define DATA32_SUPPORT
static struct mmcdevice handleNAND;
static struct mmcdevice handleSD;
mmcdevice *getMMCDevice(int drive)
{
if(drive==0) return &handleNAND;
return &handleSD;
}
int __attribute__((noinline)) geterror(struct mmcdevice *ctx)
{
//if(ctx->error == 0x4) return -1;
//else return 0;
return (ctx->error << 29) >> 31;
}
void __attribute__((noinline)) inittarget(struct mmcdevice *ctx)
{
sdmmc_mask16(REG_SDPORTSEL,0x3,(u16)ctx->devicenumber);
setckl(ctx->clk);
if (ctx->SDOPT == 0) {
sdmmc_mask16(REG_SDOPT, 0, 0x8000);
} else {
sdmmc_mask16(REG_SDOPT, 0x8000, 0);
}
}
void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
{
bool getSDRESP = (cmd << 15) >> 31;
u16 flags = (cmd << 15) >> 31;
const bool readdata = cmd & 0x20000;
const bool writedata = cmd & 0x40000;
if (readdata || writedata)
flags |= TMIO_STAT0_DATAEND;
ctx->error = 0;
while (sdmmc_read16(REG_SDSTATUS1) & TMIO_STAT1_CMD_BUSY); //mmc working?
sdmmc_write16(REG_SDIRMASK0,0);
sdmmc_write16(REG_SDIRMASK1,0);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
#ifdef DATA32_SUPPORT
if (readdata)
sdmmc_mask16(REG_SDDATACTL32, 0x1000, 0x800);
if (writedata)
sdmmc_mask16(REG_SDDATACTL32, 0x800, 0x1000);
#else
sdmmc_mask16(REG_SDDATACTL32,0x1800,0);
#endif
sdmmc_write16(REG_SDCMDARG0,args &0xFFFF);
sdmmc_write16(REG_SDCMDARG1,args >> 16);
sdmmc_write16(REG_SDCMD,cmd &0xFFFF);
u32 size = ctx->size;
u16 *dataPtr = (u16*)ctx->data;
#ifdef DATA32_SUPPORT
u32 *dataPtr32 = (u32*)ctx->data;
#endif
bool useBuf = ( NULL != dataPtr );
#ifdef DATA32_SUPPORT
bool useBuf32 = (useBuf && (0 == (3 & ((u32)dataPtr))));
#endif
u16 status0 = 0;
while(true) {
u16 status1 = sdmmc_read16(REG_SDSTATUS1);
if (status1 & TMIO_STAT1_RXRDY) {
if (readdata && useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_RXRDY);
if (size > 0x1FF) {
#ifdef DATA32_SUPPORT
if (useBuf32) {
for(int i = 0; i<0x200; i+=4)
*dataPtr32++ = sdmmc_read32(REG_SDFIFO32);
} else {
#endif
for(int i = 0; i<0x200; i+=2)
*dataPtr++ = sdmmc_read16(REG_SDFIFO);
#ifdef DATA32_SUPPORT
}
#endif
size -= 0x200;
}
}
}
if (status1 & TMIO_STAT1_TXRQ) {
if (writedata && useBuf) {
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
//sdmmc_write16(REG_SDSTATUS1,~TMIO_STAT1_TXRQ);
if (size > 0x1FF) {
#ifdef DATA32_SUPPORT
for (int i = 0; i<0x200; i+=4)
sdmmc_write32(REG_SDFIFO32,*dataPtr32++);
#else
for (int i = 0; i<0x200; i+=2)
sdmmc_write16(REG_SDFIFO,*dataPtr++);
#endif
size -= 0x200;
}
}
}
if (status1 & TMIO_MASK_GW) {
ctx->error |= 4;
break;
}
if (!(status1 & TMIO_STAT1_CMD_BUSY)) {
status0 = sdmmc_read16(REG_SDSTATUS0);
if (sdmmc_read16(REG_SDSTATUS0) & TMIO_STAT0_CMDRESPEND)
ctx->error |= 0x1;
if (status0 & TMIO_STAT0_DATAEND)
ctx->error |= 0x2;
if ((status0 & flags) == flags)
break;
}
}
ctx->stat0 = sdmmc_read16(REG_SDSTATUS0);
ctx->stat1 = sdmmc_read16(REG_SDSTATUS1);
sdmmc_write16(REG_SDSTATUS0,0);
sdmmc_write16(REG_SDSTATUS1,0);
if (getSDRESP != 0) {
ctx->ret[0] = sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16);
ctx->ret[1] = sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16);
ctx->ret[2] = sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16);
ctx->ret[3] = sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16);
}
}
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in)
{
if (handleSD.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleSD);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
handleSD.data = in;
handleSD.size = numsectors << 9;
sdmmc_send_command(&handleSD,0x52C19,sector_no);
return geterror(&handleSD);
}
int __attribute__((noinline)) sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out)
{
if (handleSD.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleSD);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write16(REG_SDBLKCOUNT32,numsectors);
sdmmc_write16(REG_SDBLKLEN32,0x200);
#endif
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
handleSD.data = out;
handleSD.size = numsectors << 9;
sdmmc_send_command(&handleSD,0x33C12,sector_no);
return geterror(&handleSD);
}
int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out)
{
if (handleNAND.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleNAND);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write32(REG_SDBLKCOUNT32,numsectors);
#else
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
#endif
handleNAND.data = out;
handleNAND.size = numsectors << 9;
sdmmc_send_command(&handleNAND,0x33C12,sector_no);
inittarget(&handleSD);
return geterror(&handleNAND);
}
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in) //experimental
{
if (handleNAND.isSDHC == 0)
sector_no <<= 9;
inittarget(&handleNAND);
sdmmc_write16(REG_SDSTOP,0x100);
#ifdef DATA32_SUPPORT
sdmmc_write32(REG_SDBLKCOUNT32,numsectors);
#else
sdmmc_write16(REG_SDBLKCOUNT,numsectors);
#endif
handleNAND.data = in;
handleNAND.size = numsectors << 9;
sdmmc_send_command(&handleNAND,0x52C19,sector_no);
inittarget(&handleSD);
return geterror(&handleNAND);
}
u32 calcSDSize(u8* csd, int type)
{
u32 result = 0;
u8 temp = csd[0xE];
//int temp3 = type;
switch (type) {
case -1:
type = temp >> 6;
break;
case 0:
{
u32 temp = (csd[0x7] << 0x2 | csd[0x8] << 0xA | csd[0x6] >> 0x6 | (csd[0x9] & 0xF) << 0x10) & 0xFFF;
u32 temp2 = temp * (1 << (csd[0x9] & 0xF));
u32 retval = temp2 * (1 << (((csd[0x4] >> 7 | csd[0x5] << 1) & 7) + 2));
result = retval >> 9;
break;
}
case 1:
result = (((csd[0x7] & 0x3F) << 0x10 | csd[0x6] << 8 | csd[0x5]) + 1) << 0xA;
break;
default:
result = 0;
break;
}
return result;
}
void InitSD()
{
//NAND
handleNAND.isSDHC = 0;
handleNAND.SDOPT = 0;
handleNAND.res = 0;
handleNAND.initarg = 1;
handleNAND.clk = 0x80;
handleNAND.devicenumber = 1;
//SD
handleSD.isSDHC = 0;
handleSD.SDOPT = 0;
handleSD.res = 0;
handleSD.initarg = 0;
handleSD.clk = 0x80;
handleSD.devicenumber = 0;
//sdmmc_mask16(0x100,0x800,0);
//sdmmc_mask16(0x100,0x1000,0);
//sdmmc_mask16(0x100,0x0,0x402);
//sdmmc_mask16(0xD8,0x22,0x2);
//sdmmc_mask16(0x100,0x2,0);
//sdmmc_mask16(0xD8,0x22,0);
//sdmmc_write16(0x104,0);
//sdmmc_write16(0x108,1);
//sdmmc_mask16(REG_SDRESET,1,0); //not in new Version -- nintendo's code does this
//sdmmc_mask16(REG_SDRESET,0,1); //not in new Version -- nintendo's code does this
//sdmmc_mask16(0x20,0,0x31D);
//sdmmc_mask16(0x22,0,0x837F);
//sdmmc_mask16(0xFC,0,0xDB);
//sdmmc_mask16(0xFE,0,0xDB);
////sdmmc_write16(REG_SDCLKCTL,0x20);
////sdmmc_write16(REG_SDOPT,0x40EE);
////sdmmc_mask16(0x02,0x3,0);
//sdmmc_write16(REG_SDCLKCTL,0x40);
//sdmmc_write16(REG_SDOPT,0x40EB);
//sdmmc_mask16(0x02,0x3,0);
//sdmmc_write16(REG_SDBLKLEN,0x200);
//sdmmc_write16(REG_SDSTOP,0);
*(vu16*)0x10006100 &= 0xF7FFu; //SDDATACTL32
*(vu16*)0x10006100 &= 0xEFFFu; //SDDATACTL32
#ifdef DATA32_SUPPORT
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
#else
*(vu16*)0x10006100 |= 0x402u; //SDDATACTL32
#endif
*(vu16*)0x100060D8 = (*(vu16*)0x100060D8 & 0xFFDD) | 2;
#ifdef DATA32_SUPPORT
*(vu16*)0x10006100 &= 0xFFFFu; //SDDATACTL32
*(vu16*)0x100060D8 &= 0xFFDFu; //SDDATACTL
*(vu16*)0x10006104 = 512; //SDBLKLEN32
#else
*(vu16*)0x10006100 &= 0xFFFDu; //SDDATACTL32
*(vu16*)0x100060D8 &= 0xFFDDu; //SDDATACTL
*(vu16*)0x10006104 = 0; //SDBLKLEN32
#endif
*(vu16*)0x10006108 = 1; //SDBLKCOUNT32
*(vu16*)0x100060E0 &= 0xFFFEu; //SDRESET
*(vu16*)0x100060E0 |= 1u; //SDRESET
*(vu16*)0x10006020 |= TMIO_MASK_ALL; //SDIR_MASK0
*(vu16*)0x10006022 |= TMIO_MASK_ALL>>16; //SDIR_MASK1
*(vu16*)0x100060FC |= 0xDBu; //SDCTL_RESERVED7
*(vu16*)0x100060FE |= 0xDBu; //SDCTL_RESERVED8
*(vu16*)0x10006002 &= 0xFFFCu; //SDPORTSEL
#ifdef DATA32_SUPPORT
*(vu16*)0x10006024 = 0x20;
*(vu16*)0x10006028 = 0x40EE;
#else
*(vu16*)0x10006024 = 0x40; //Nintendo sets this to 0x20
*(vu16*)0x10006028 = 0x40EB; //Nintendo sets this to 0x40EE
#endif
*(vu16*)0x10006002 &= 0xFFFCu; ////SDPORTSEL
*(vu16*)0x10006026 = 512; //SDBLKLEN
*(vu16*)0x10006008 = 0; //SDSTOP
inittarget(&handleSD);
}
int Nand_Init()
{
inittarget(&handleNAND);
ioDelay(0xF000);
sdmmc_send_command(&handleNAND,0,0);
do {
do {
sdmmc_send_command(&handleNAND,0x10701,0x100000);
} while ( !(handleNAND.error & 1) );
} while((handleNAND.ret[0] & 0x80000000) == 0);
sdmmc_send_command(&handleNAND,0x10602,0x0);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10403,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10609,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
handleNAND.total_size = calcSDSize((u8*)&handleNAND.ret[0],0);
handleNAND.clk = 1;
setckl(1);
sdmmc_send_command(&handleNAND,0x10407,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
handleNAND.SDOPT = 1;
sdmmc_send_command(&handleNAND,0x10506,0x3B70100);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10506,0x3B90100);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x1040D,handleNAND.initarg << 0x10);
if (handleNAND.error & 0x4) return -1;
sdmmc_send_command(&handleNAND,0x10410,0x200);
if (handleNAND.error & 0x4) return -1;
handleNAND.clk |= 0x200;
inittarget(&handleSD);
return 0;
}
int SD_Init()
{
inittarget(&handleSD);
//ioDelay(0x3E8);
ioDelay(0xF000);
sdmmc_send_command(&handleSD,0,0);
sdmmc_send_command(&handleSD,0x10408,0x1AA);
//u32 temp = (handleSD.ret[0] == 0x1AA) << 0x1E;
u32 temp = (handleSD.error & 0x1) << 0x1E;
//int count = 0;
u32 temp2 = 0;
do {
do {
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
sdmmc_send_command(&handleSD,0x10769,0x00FF8000 | temp);
temp2 = 1;
} while ( !(handleSD.error & 1) );
} while((handleSD.ret[0] & 0x80000000) == 0);
//do
//{
// sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
// sdmmc_send_command(&handleSD,0x10769,0x00FF8000 | temp);
//
//}
//while(!(handleSD.ret[0] & 0x80000000));
if(!((handleSD.ret[0] >> 30) & 1) || !temp)
temp2 = 0;
handleSD.isSDHC = temp2;
//handleSD.isSDHC = (handleSD.ret[0] & 0x40000000);
sdmmc_send_command(&handleSD,0x10602,0);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10403,0);
if (handleSD.error & 0x4) return -1;
handleSD.initarg = handleSD.ret[0] >> 0x10;
sdmmc_send_command(&handleSD,0x10609,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
handleSD.total_size = calcSDSize((u8*)&handleSD.ret[0],-1);
handleSD.clk = 1;
setckl(1);
sdmmc_send_command(&handleSD,0x10507,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10437,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
handleSD.SDOPT = 1;
sdmmc_send_command(&handleSD,0x10446,0x2);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x1040D,handleSD.initarg << 0x10);
if (handleSD.error & 0x4) return -1;
sdmmc_send_command(&handleSD,0x10410,0x200);
if (handleSD.error & 0x4) return -1;
handleSD.clk |= 0x200;
return 0;
}
void sdmmc_sdcard_init()
{
InitSD();
Nand_Init();
SD_Init();
}

171
source/fatfs/sdmmc/sdmmc.h Normal file
View File

@ -0,0 +1,171 @@
// Copyright 2014 Normmatt
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common.h"
#define SDMMC_BASE 0x10006000u
#define REG_SDCMD 0x00
#define REG_SDPORTSEL 0x02
#define REG_SDCMDARG 0x04
#define REG_SDCMDARG0 0x04
#define REG_SDCMDARG1 0x06
#define REG_SDSTOP 0x08
#define REG_SDBLKCOUNT 0x0a
#define REG_SDRESP0 0x0c
#define REG_SDRESP1 0x0e
#define REG_SDRESP2 0x10
#define REG_SDRESP3 0x12
#define REG_SDRESP4 0x14
#define REG_SDRESP5 0x16
#define REG_SDRESP6 0x18
#define REG_SDRESP7 0x1a
#define REG_SDSTATUS0 0x1c
#define REG_SDSTATUS1 0x1e
#define REG_SDIRMASK0 0x20
#define REG_SDIRMASK1 0x22
#define REG_SDCLKCTL 0x24
#define REG_SDBLKLEN 0x26
#define REG_SDOPT 0x28
#define REG_SDFIFO 0x30
#define REG_SDDATACTL 0xd8
#define REG_SDRESET 0xe0
#define REG_SDPROTECTED 0xf6 //bit 0 determines if sd is protected or not?
#define REG_SDDATACTL32 0x100
#define REG_SDBLKLEN32 0x104
#define REG_SDBLKCOUNT32 0x108
#define REG_SDFIFO32 0x10C
#define REG_CLK_AND_WAIT_CTL 0x138
#define REG_RESET_SDIO 0x1e0
#define TMIO_STAT0_CMDRESPEND 0x0001
#define TMIO_STAT0_DATAEND 0x0004
#define TMIO_STAT0_CARD_REMOVE 0x0008
#define TMIO_STAT0_CARD_INSERT 0x0010
#define TMIO_STAT0_SIGSTATE 0x0020
#define TMIO_STAT0_WRPROTECT 0x0080
#define TMIO_STAT0_CARD_REMOVE_A 0x0100
#define TMIO_STAT0_CARD_INSERT_A 0x0200
#define TMIO_STAT0_SIGSTATE_A 0x0400
#define TMIO_STAT1_CMD_IDX_ERR 0x0001
#define TMIO_STAT1_CRCFAIL 0x0002
#define TMIO_STAT1_STOPBIT_ERR 0x0004
#define TMIO_STAT1_DATATIMEOUT 0x0008
#define TMIO_STAT1_RXOVERFLOW 0x0010
#define TMIO_STAT1_TXUNDERRUN 0x0020
#define TMIO_STAT1_CMDTIMEOUT 0x0040
#define TMIO_STAT1_RXRDY 0x0100
#define TMIO_STAT1_TXRQ 0x0200
#define TMIO_STAT1_ILL_FUNC 0x2000
#define TMIO_STAT1_CMD_BUSY 0x4000
#define TMIO_STAT1_ILL_ACCESS 0x8000
//Comes from TWLSDK mongoose.tef DWARF info
#define SDMC_NORMAL 0x00000000
#define SDMC_ERR_COMMAND 0x00000001
#define SDMC_ERR_CRC 0x00000002
#define SDMC_ERR_END 0x00000004
#define SDMC_ERR_TIMEOUT 0x00000008
#define SDMC_ERR_FIFO_OVF 0x00000010
#define SDMC_ERR_FIFO_UDF 0x00000020
#define SDMC_ERR_WP 0x00000040
#define SDMC_ERR_ABORT 0x00000080
#define SDMC_ERR_FPGA_TIMEOUT 0x00000100
#define SDMC_ERR_PARAM 0x00000200
#define SDMC_ERR_R1_STATUS 0x00000800
#define SDMC_ERR_NUM_WR_SECTORS 0x00001000
#define SDMC_ERR_RESET 0x00002000
#define SDMC_ERR_ILA 0x00004000
#define SDMC_ERR_INFO_DETECT 0x00008000
#define SDMC_STAT_ERR_UNKNOWN 0x00080000
#define SDMC_STAT_ERR_CC 0x00100000
#define SDMC_STAT_ERR_ECC_FAILED 0x00200000
#define SDMC_STAT_ERR_CRC 0x00800000
#define SDMC_STAT_ERR_OTHER 0xf9c70008
#define TMIO_MASK_ALL 0x837f031d
#define TMIO_MASK_GW (TMIO_STAT1_ILL_ACCESS | TMIO_STAT1_CMDTIMEOUT | TMIO_STAT1_TXUNDERRUN | TMIO_STAT1_RXOVERFLOW | \
TMIO_STAT1_DATATIMEOUT | TMIO_STAT1_STOPBIT_ERR | TMIO_STAT1_CRCFAIL | TMIO_STAT1_CMD_IDX_ERR)
#define TMIO_MASK_READOP (TMIO_STAT1_RXRDY | TMIO_STAT1_DATAEND)
#define TMIO_MASK_WRITEOP (TMIO_STAT1_TXRQ | TMIO_STAT1_DATAEND)
typedef struct mmcdevice {
u8* data;
u32 size;
u32 error;
u16 stat0;
u16 stat1;
u32 ret[4];
u32 initarg;
u32 isSDHC;
u32 clk;
u32 SDOPT;
u32 devicenumber;
u32 total_size; //size in sectors of the device
u32 res;
} mmcdevice;
/*int sdmmc_sdcard_init();
void sdmmc_sdcard_readsector(uint32_t sector_no, void *out);
void sdmmc_sdcard_readsectors(uint32_t sector_no, uint32_t numsectors, void *out);
void sdmmc_sdcard_writesector(uint32_t sector_no, void *in);
void sdmmc_sdcard_writesectors(uint32_t sector_no, uint32_t numsectors, void *in);
void sdmmc_blktransferinit();*/
void sdmmc_sdcard_init();
int sdmmc_sdcard_readsector(u32 sector_no, u8 *out);
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_sdcard_writesector(u32 sector_no, u8 *in);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, u8 *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, u8 *in);
mmcdevice *getMMCDevice(int drive);
void InitSDMMC();
int Nand_Init();
int SD_Init();
static inline u16 sdmmc_read16(u16 reg) {
return *(vu16*)(SDMMC_BASE + reg);
}
static inline void sdmmc_write16(u16 reg, u16 val) {
*(vu16*)(SDMMC_BASE + reg) = val;
}
static inline u32 sdmmc_read32(u16 reg) {
return *(vu32*)(SDMMC_BASE + reg);
}
static inline void sdmmc_write32(u16 reg, u32 val) {
*(vu32*)(SDMMC_BASE + reg) = val;
}
static inline void sdmmc_mask16(u16 reg, const u16 clear, const u16 set) {
u16 val = sdmmc_read16(reg);
val &= ~clear;
val |= set;
sdmmc_write16(reg, val);
}
static inline void setckl(u32 data)
{
sdmmc_mask16(REG_SDCLKCTL, 0x100, 0);
sdmmc_mask16(REG_SDCLKCTL, 0x2FF, data & 0x2FF);
sdmmc_mask16(REG_SDCLKCTL, 0x0, 0x100);
}

90
source/firm.c Normal file
View File

@ -0,0 +1,90 @@
/*
* firm.c
* by Reisyukaku
*/
#include "firm.h"
#include "patches.h"
#include "memory.h"
#include "types.h"
#include "fs.h"
#include "emunand.h"
firmHeader *firmLocation = (firmHeader *)0x24000000;
const u32 firmSize = 0xF1000;
firmSectionHeader *section;
void loadSplash(void){
fileRead((u8 *)0x20047000, "/rei/splash.bin", 0x46500); //ghetto because address varies i think
while(((~*(unsigned *)0x10146000) & 0xFFF) == (1 << 3) ? 0 : 1); //Press start to boot
}
void loadFirm(void){
//Read FIRM from SD card and write to FCRAM
fileRead((u8*)firmLocation, "/rei/firmware.bin", firmSize);
section = firmLocation->section;
}
void patchFirm(void){
//Part1: Add emunand parsing code
u32 offset = 0;
u32 header = 0;
if(getEmunand(&offset, &header) == 1){
fileRead((u8*)emuCode, "/rei/emunand/emunand.bin", 0);
u32 *pos_offset = memsearch((u8*)emuCode, "NAND", 0x218, 4);
u32 *pos_header = memsearch((u8*)emuCode, "NCSD", 0x218, 4);
memcpy((void *)pos_offset, (void *)offset, 4);
memcpy((void *)pos_header, (void *)header, 4);
}
//Part2: Add emunand hooks
memcpy((u8*)emuHook1, eh1, sizeof(eh1));
memcpy((u8*)emuHook2, eh2, sizeof(eh2));
memcpy((u8*)emuHook3, eh3, sizeof(eh3));
memcpy((u8*)emuHook4, eh4, sizeof(eh4));
//Part3: Disable signature checks
memcpy((u8*)patch1, p1, sizeof(p1));
memcpy((u8*)patch2, p2, sizeof(p2));
//Part4: Create arm9 thread
fileRead((u8*)threadCode, "/rei/thread/arm9.bin", 0);
memcpy((u8*)threadHook1, th1, sizeof(th1));
memcpy((u8*)threadHook2, th2, sizeof(th2));
}
void launchFirm(void){
//Set MPU
__asm__ (
"msr cpsr_c, #0xDF\n\t"
"ldr r0, =0x10000035\n\t"
"ldr r4, =0x18000035\n\t"
"mcr p15, 0, r0, c6, c3, 0\n\t"
"mcr p15, 0, r4, c6, c4, 0\n\t"
"mrc p15, 0, r0, c2, c0, 0\n\t"
"mrc p15, 0, r4, c2, c0, 1\n\t"
"mrc p15, 0, r1, c3, c0, 0\n\t"
"mrc p15, 0, r2, c5, c0, 2\n\t"
"mrc p15, 0, r3, c5, c0, 3\n\t"
"orr r0, r0, #0x30\n\t"
"orr r4, r4, #0x30\n\t"
"orr r1, r1, #0x30\n\t"
"bic r2, r2, #0xF0000\n\t"
"bic r3, r3, #0xF0000\n\t"
"orr r2, r2, #0x30000\n\t"
"orr r3, r3, #0x30000\n\t"
"mcr p15, 0, r0, c2, c0, 0\n\t"
"mcr p15, 0, r4, c2, c0, 1\n\t"
"mcr p15, 0, r1, c3, c0, 0\n\t"
"mcr p15, 0, r2, c5, c0, 2\n\t"
"mcr p15, 0, r3, c5, c0, 3\n\t"
::: "r0", "r1", "r2", "r3", "r4"
);
//Copy firm partitions to respective memory locations
memcpy(section[0].address, (u8*)firmLocation + section[0].offset, section[0].size);
memcpy(section[1].address, (u8*)firmLocation + section[1].offset, section[1].size);
memcpy(section[2].address, (u8*)firmLocation + section[2].offset, section[2].size);
*(u32 *)0x1FFFFFF8 = (u32)firmLocation->arm11Entry;
//Final jump to arm9 binary
((void (*)())0x801B01C)();
}

13
source/firm.h Normal file
View File

@ -0,0 +1,13 @@
/*
* firm.h
* by Reisyukaku
*/
#ifndef FIRM_INC
#define FIRM_INC
void loadSplash(void);
void loadFirm(void);
void patchFirm(void);
void launchFirm(void);
#endif

144
source/font.h Normal file
View File

@ -0,0 +1,144 @@
/*
This file was autogenerated by raw2c.
Visit http://www.devkitpro.org
*/
//---------------------------------------------------------------------------------
#ifndef _font_h_
#define _font_h_
//---------------------------------------------------------------------------------
static const unsigned char font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x3c, 0x3c, 0x18, 0xff, 0xe7, 0x18, 0x3c, 0x00,
0x10, 0x38, 0x7c, 0xfe, 0xee, 0x10, 0x38, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x08, 0x0c, 0x0a, 0x0a, 0x08, 0x78, 0xf0, 0x00,
0x18, 0x14, 0x1a, 0x16, 0x72, 0xe2, 0x0e, 0x1c, 0x10, 0x54, 0x38, 0xee, 0x38, 0x54, 0x10, 0x00,
0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x00, 0x1c, 0x22, 0x38, 0x44, 0x44, 0x38, 0x88, 0x70,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x5a, 0x18, 0x5a, 0x3c, 0x18, 0x7e,
0x18, 0x3c, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x5a, 0x3c, 0x18, 0x00,
0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00,
0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,
0x6c, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
0x10, 0x7c, 0xd0, 0x7c, 0x16, 0xfc, 0x10, 0x00, 0x00, 0x66, 0xac, 0xd8, 0x36, 0x6a, 0xcc, 0x00,
0x38, 0x4c, 0x38, 0x78, 0xce, 0xcc, 0x7a, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x00,
0x7c, 0xce, 0xde, 0xf6, 0xe6, 0xe6, 0x7c, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x7c, 0xc6, 0x06, 0x1c, 0x70, 0xc6, 0xfe, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00,
0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfe, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00,
0x7c, 0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00, 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x10, 0x20,
0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
0x7c, 0x82, 0x9e, 0xa6, 0x9e, 0x80, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00,
0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xce, 0xc6, 0x7e, 0x00,
0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x06,
0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0xc6, 0xc0, 0x7c, 0x06, 0xc6, 0x7c, 0x00,
0x7e, 0x5a, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00,
0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00,
0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00,
0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
0x1c, 0x36, 0x30, 0x78, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x78,
0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xd6, 0xd6, 0xd6, 0x00,
0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
0x00, 0x00, 0xde, 0x76, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x7c, 0x06, 0x7c, 0x00,
0x10, 0x30, 0xfc, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00,
0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x0e, 0x18, 0x18, 0x30, 0x18, 0x18, 0x0e, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xe0, 0x00,
0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x0e, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x7c, 0x82, 0x38, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0xc0, 0x7c, 0x18, 0x70,
0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
0xe0, 0x10, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x38, 0x38, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
0x0e, 0x10, 0xfe, 0x60, 0x78, 0x60, 0xfe, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x7e, 0xd0, 0x7e, 0x00,
0x7e, 0xc8, 0xc8, 0xfe, 0xc8, 0xc8, 0xce, 0x00, 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0xe0, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0x7c, 0x82, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0xe0, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x7c, 0xd6, 0xd0, 0xd6, 0x7c, 0x18, 0x00,
0x38, 0x6c, 0x60, 0xf0, 0x60, 0xf2, 0xdc, 0x00, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x00,
0xf8, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0x06, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
0x0e, 0x10, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, 0x0e, 0x10, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x0e, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x0e, 0x10, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
0x66, 0x98, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x98, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0x00,
0x38, 0x0c, 0x3c, 0x34, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
0x30, 0x00, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc0, 0xc8, 0xd0, 0xfe, 0x46, 0x8c, 0x1e, 0x00,
0xc0, 0xc8, 0xd0, 0xec, 0x5c, 0xbe, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00,
0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00,
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x74, 0xcc, 0xc8, 0xdc, 0x76, 0x00, 0x78, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xdc, 0x40,
0xfe, 0x62, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c, 0x6c, 0x48, 0x00,
0xfe, 0x62, 0x30, 0x18, 0x30, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8, 0xc8, 0x70, 0x00,
0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x00, 0x00, 0x7e, 0xd8, 0x18, 0x18, 0x10, 0x00,
0x38, 0x10, 0x7c, 0xd6, 0xd6, 0x7c, 0x10, 0x38, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00,
0x7c, 0xc6, 0xc6, 0xc6, 0x6c, 0x28, 0xee, 0x00, 0x3c, 0x22, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
0x00, 0x00, 0x66, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x06, 0x7c, 0x9e, 0xf2, 0x7c, 0xc0, 0x00,
0x00, 0x00, 0x7c, 0xc0, 0xf8, 0xc0, 0x7c, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00,
0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
0x30, 0x18, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x7c, 0x00,
0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x00,
0xd8, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const int font_size = sizeof(font);
//---------------------------------------------------------------------------------
#endif //_font_h_
//---------------------------------------------------------------------------------

72
source/fs.c Normal file
View File

@ -0,0 +1,72 @@
/*
* fs.c
*/
#include <stddef.h>
#include "fs.h"
#include "fatfs/ff.h"
static FATFS fs;
int mountSD()
{
if (f_mount(&fs, "0:", 1) != FR_OK) {
//printF("Failed to mount SD card!");
return 1;
}
//printF("Mounted SD card");
return 0;
}
int unmountSD()
{
if (f_mount(NULL, "0:", 1) != FR_OK) {
//printF("Failed to mount SD card!");
return 1;
}
//printF("Unmounted SD card");
return 0;
}
int fileReadOffset(u8 *dest, const char *path, u32 size, u32 offset){
FRESULT fr;
FIL fp;
u32 br = 0;
fr = f_open(&fp, path, FA_READ);
if (fr != FR_OK)goto error;
if (!size) size = f_size(&fp);
if (offset) {
fr = f_lseek(&fp, offset);
if (fr != FR_OK) goto error;
}
fr = f_read(&fp, dest, size, &br);
if (fr != FR_OK) goto error;
fr = f_close(&fp);
if (fr != FR_OK) goto error;
return 0;
error:
f_close(&fp);
return fr;
}
int fileRead(u8 *dest, const char *path, u32 size){
return fileReadOffset(dest, path, size, 0);
}
int fileWrite(const u8 *buffer, const char *path, u32 size){
FRESULT fr;
FIL fp;
u32 br = 0;
if(f_open(&fp, path, FA_WRITE | FA_OPEN_ALWAYS) == FR_OK){
fr = f_write(&fp, buffer, size, &br);
f_close(&fp);
if (fr == FR_OK && br == size) return 0;
}
return fr;
}

16
source/fs.h Normal file
View File

@ -0,0 +1,16 @@
/*
* fs.h
*/
#ifndef __fs_h__
#define __fs_h__
#include "types.h"
int mountSD();
int unmountSD();
int fileReadOffset(u8 *dest, const char *path, u32 size, u32 offset);
int fileRead(u8 *dest, const char *path, u32 size);
int fileWrite(const u8 *buffer, const char *path, u32 size);
#endif

18
source/main.c Normal file
View File

@ -0,0 +1,18 @@
/*
* main.c
* by Reisyukaku
*
* Minimalist CFW for N3DS
*/
#include "fs.h"
#include "firm.h"
int main(){
mountSD();
loadSplash();
loadFirm();
patchFirm();
launchFirm();
return 0;
}

32
source/memory.c Normal file
View File

@ -0,0 +1,32 @@
/*
* memory.c
* by Reisyukaku
*/
#include "memory.h"
void memcpy(u8 *dest, u8 *src, u32 size){
for (u32 i = 0; i < size; i++) dest[i] = src[i];
}
void memcpy32(u32 *dest, u32 *src, u32 size){
for (u32 i = 0; i < size; i++) dest[i] = src[i];
}
void memset(u8 *dest, u32 fill, u32 size){
for (u32 i = 0; i < size; i++) dest[i] = fill;
}
int memcmp(u8 *buf1, u8 *buf2, u32 size){
for (u32 i = 0; i < size; i++) {
int cmp = buf1[i] - buf2[i];
if (cmp != 0) return cmp;
}
return 0;
}
u32 *memsearch(u8 *start_pos, u8 *search, u32 size, u32 size_search){
for (u8 *pos = start_pos; pos <= start_pos + size - size_search; pos++) {
if (memcmp(pos, search, size_search) == 0) return (u32*)pos;
}
return NULL;
}

16
source/memory.h Normal file
View File

@ -0,0 +1,16 @@
/*
* memory.h
* by Reisyukaku
*/
#ifndef MEM_INC
#define MEM_INC
#include "types.h"
void memcpy(u8 *dest, u8 *src, u32 size);
void memcpy32(u32 *dest, u32 *src, u32 size);
void memset(u8 *dest, u32 fill, u32 size);
int memcmp(u8 *buf1, u8 *buf2, u32 size);
u32 *memsearch(u8 *start_pos, u8 *search, u32 size, u32 size_search);
#endif

62
source/patches.h Normal file
View File

@ -0,0 +1,62 @@
/*
* patches.h
* by Reisyukaku
*/
#ifndef PATCHES_INC
#define PATCHES_INC
#include "types.h"
#define FIRM 0x24000000
#define KERNEL9 (FIRM + 0x66A00)
#define PROC9 (FIRM + 0x7D700)
#define K9_ADDR 0x08006000
#define P9_ADDR 0x08028000
/*
* Emunand
*/
//Addresses to patch
u32 emuCode = KERNEL9 + (0x0801A4C0 - K9_ADDR);
u32 emuHook1 = KERNEL9 + (0x0801B3D4 - K9_ADDR);
u32 emuHook2 = PROC9 + (0x080282F8 - P9_ADDR);
u32 emuHook3 = PROC9 + (0x0807877E - P9_ADDR);
u32 emuHook4 = PROC9 + (0x080787BE - P9_ADDR);
//Patches
u8 eh1[0x2C] = {
0x03, 0x00, 0x36, 0x00, 0x00, 0x00, 0x10, 0x10, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, 0x36, 0x00,
0x00, 0x00, 0x00, 0x20, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08,
0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x08
};
u8 eh2[0x14] = {
0x03, 0x4A, 0x05, 0x21, 0x25, 0x20, 0x2F, 0xF0, 0xAB, 0xF8, 0x37, 0xF0, 0x6F, 0xFB, 0x70, 0xBD,
0xC8, 0xA6, 0x01, 0x08
}; //Sets Slot0x25KeyX
u8 eh3[0x0A] = {0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0xC0, 0xA4, 0x01, 0x08}; //Branch to first emunand function
u8 eh4[0x0A] = {0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0xB0, 0xA5, 0x01, 0x08}; //Branch to second emunand function
/*
* Sig checks
*/
//Addresses to patch
u32 patch1 = PROC9 + (0x08063374 - P9_ADDR);
u32 patch2 = PROC9 + (0x0805D498 - P9_ADDR);
//Patches
u8 p1[2] = {0x00, 0x20};
u8 p2[4] = {0x00, 0x20, 0x70, 0x47};
/*
* Arm9 thread
*/
//Addresses to patch
u32 threadCode = KERNEL9 + (0x0801A6E0 - K9_ADDR);
u32 threadHook1 = PROC9 + (0x080860B0 - P9_ADDR);
u32 threadHook2 = PROC9 + (0x080860E4 - P9_ADDR);
//Patches
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5};
u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08};
#endif

48
source/start.s Normal file
View File

@ -0,0 +1,48 @@
.section .text.start
.align 4
.global _start
_start:
@ Change the stack pointer
mov sp, #0x27000000
@ Sets MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k
ldr r1, =0x01FF801D @ 01ff8000 32k
ldr r2, =0x08000027 @ 08000000 1M
ldr r3, =0x10000021 @ 10000000 128k
ldr r4, =0x10100025 @ 10100000 512k
ldr r5, =0x20000035 @ 20000000 128M
ldr r6, =0x2800801B @ 28008000 16k
ldr r7, =0x1800002D @ 18000000 8M
ldr r8, =0x33333336
ldr r9, =0x60600666
mov r10, #0x25
mov r11, #0x25
mov r12, #0x25
mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0
mcr p15, 0, r3, c6, c3, 0
mcr p15, 0, r4, c6, c4, 0
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
mcr p15, 0, r8, c5, c0, 2 @ Enable data r/w for all regions
mcr p15, 0, r9, c5, c0, 3 @ Enable inst read for 0, 1, 2, 5, 7
mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5
mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5
mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5
@ Enables all the settings we specified above
ldr r0, =0x5307D
mcr p15, 0, r0, c1, c0, 0 @ cp15 ctl register enable mpu, enable cache and use alt vector table
@ Undocumented: Fixes mounting of SDMC
ldr r0, =0x10000020
mov r1, #0x340
str r1, [r0]
bl main
.die:
b .die

35
source/types.h Normal file
View File

@ -0,0 +1,35 @@
/*
* types.h
* by Reisyukaku
*/
#ifndef TYPES_INC
#define TYPES_INC
#include <stdint.h>
#include <stdlib.h>
//Common data types
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
//FIRM Header layout
typedef struct firmSectionHeader {
u32 offset;
u8 *address;
u32 size;
u32 procType;
u8 hash[0x20];
} firmSectionHeader;
typedef struct firmHeader {
u32 magic;
u32 reserved1;
u8 *arm11Entry;
u8 *arm9Entry;
u8 reserved2[0x30];
firmSectionHeader section[4];
} firmHeader;
#endif

24
thread/3ds.ld Normal file
View File

@ -0,0 +1,24 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
/*0x080C3EE0*/
ENTRY(_start)
SECTIONS
{
. = 0x0801A6E0;
start_addr = .;
.text.start : { *(.text.start) }
.text : { *(.text) *(.text*) }
.rodata : { *(.rodata) *(.rodata*) }
.data : { *(.data) *(.data*) }
.bss : { *(.bss) *(.bss*) }
/*. = ALIGN(32);*/
/*.stack : {
stack_start = .;
. += 0x40;
. = ALIGN(32);
stack_end = .;
}*/
total_size = . - start_addr;
}

16
thread/Makefile Normal file
View File

@ -0,0 +1,16 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
SFLAGS=-c -mcpu=arm946e-s -march=armv5te -mlittle-endian -fshort-wchar
CFLAGS=$(SFLAGS) -std=c99
all:
$(CC) -g source/thread.c source/lib.c $(CFLAGS)
$(CC) -g source/_start.s source/FS.S -I source $(SFLAGS)
$(CC) -nostdlib -T 3ds.ld _start.o thread.o lib.o FS.o
$(OBJCOPY) -O binary a.out arm9.bin
rm -f *.o *.out

9
thread/source/FS.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef FS_H
#define FS_H
#include <stdio.h>
extern unsigned int fopen9(void *handle, wchar_t* name, unsigned int flag);
extern void fwrite9(void* handle, unsigned int* bytesWritten, void* dst, unsigned int size);
extern void fread9(void* handle, unsigned int* bytesRead, void *src, unsigned int size);
extern void fclose9(void *handle);
#endif

41
thread/source/FS.s Normal file
View File

@ -0,0 +1,41 @@
.text
.thumb
.global fopen9
.type fopen9, %function
fopen9:
push {r0-r6, lr}
ldr r4, =0x0805B015
blx r4
pop {r0-r6, pc}
.pool
.thumb
.global fwrite9
.type fwrite9, %function
fwrite9:
push {r4, lr}
ldr r4, =0x0805C379
blx r4
pop {r4, pc}
.pool
.thumb
.global fread9
.type fread9, %function
fread9:
push {r4, lr}
ldr r4, =0x0804D855
blx r4
pop {r4, pc}
.pool
.thumb
.global fclose9
.type fclose9, %function
fclose9:
push {r4, lr}
ldr r4, =0x08053C6D
blx r4
pop {r4, pc}
.pool

21
thread/source/_start.s Normal file
View File

@ -0,0 +1,21 @@
.arm
.global thread
.global _start
_start:
push {r0-r12 , lr}
ldr r0, =0x08000c00
mov r1, #0xA00
mov r2, #0x0
thread_stack_loop:
str r2, [r0], #0x4
subs r1, r1, #4
bgt thread_stack_loop
mov r0, #0x3F @ thread priority
ldr r1, =thread @ thread_addr
mov r2, #0x0 @ arg
ldr r3, =0x08000c00 @ StackTop
ldr r4, =0x1
svc 0x8
pop {r0-r12 , lr}
ldr r0, =0x80CB0A8
ldr pc, =0x080860B4

36
thread/source/lib.c Normal file
View File

@ -0,0 +1,36 @@
#include "lib.h"
void *memset(void * ptr, int value, unsigned int num){
unsigned char *p = ptr;
while (num) {
*p++ = value;
num--;
}
return ptr;
}
int strcomp(char* s1, char* s2, unsigned int size){
for(int i = 0; i < size; i++){
if(s1[i] != s2[i]) return 0;
}
return 1;
}
void strcopy(char* dest, char* source, unsigned int size){
for(int i = 0; i < size*2; i++) dest[i] = source[i];
}
int memcmp(void* buf1, void* buf2, int size){
int equal = 0;
for(int i = 0; i < size; i++){
if(*((unsigned char*)buf1 + i) != *((unsigned char*)buf2 + i)){
equal = i;
break;
}
}
return equal;
}
unsigned isPressed(unsigned bitfield){
return ((~*(unsigned *)0x10146000) & 0xFFF) == (bitfield & 0xFFF) ? 1 : 0;
}

25
thread/source/lib.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef LIB_H
#define LIB_H
#define BUTTON_A (1 << 0)
#define BUTTON_B (1 << 1)
#define BUTTON_SELECT (1 << 2)
#define BUTTON_START (1 << 3)
#define BUTTON_RIGHT (1 << 4)
#define BUTTON_LEFT (1 << 5)
#define BUTTON_UP (1 << 6)
#define BUTTON_DOWN (1 << 7)
#define BUTTON_R1 (1 << 8)
#define BUTTON_L1 (1 << 9)
#define BUTTON_X (1 << 10)
#define BUTTON_Y (1 << 11)
#define BUTTON_ZL (1 << 14)
#define BUTTON_ZR (1 << 15)
void* memset(void * ptr, int value, unsigned int num);
int strcomp(char* s1, char*s2, unsigned int size);
void strcopy(char* dest, char* source, unsigned int size);
int memcmp(void* buf1, void* buf2, int size);
unsigned isPressed(unsigned bitfield);
#endif

87
thread/source/thread.c Normal file
View File

@ -0,0 +1,87 @@
/*
* thread.c
* by Reisyukaku
*/
#include <wchar.h>
#include <stdio.h>
#include "thread.h"
#include "lib.h"
#include "FS.h"
#define VRAM (unsigned char*)0x18000000
#define FCRAM (unsigned char*)0x20000000
#define FCRAM_EXT (unsigned char*)0x28000000
#define ARM9_MEM (unsigned char*)0x8000000
#define AXIWRAM (unsigned char*)0x1FF80000
#define TOP_FRAME 0
#define BOT_FRAME 1
unsigned char handle[32];
unsigned char bmpHead[] = {
0x42, 0x4D, 0x36, 0x65, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF0, 0x00,
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x65, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void memdump(void* filename, void* buf, unsigned int size){
unsigned int br = 0;
memset(&handle, 0, 32);
fopen9(&handle, filename, 6);
fwrite9(&handle, &br, buf, size);
fclose9(&handle);
memset(VRAM+0x1E6000, 0xFF, 0x46500);
}
void transpose (void * dst, const void * src, unsigned dim1, unsigned dim2, unsigned item_length) {
char * ptr_write;
const char * ptr_read;
unsigned x, y, z;
for (x = 0; x < dim1; x ++) for (y = 0; y < dim2; y ++) {
ptr_write = ((char *) dst) + item_length * (y * dim1 + x);
ptr_read = ((const char *) src) + item_length * (x * dim2 + y);
for (z = 0; z < item_length; z ++) *(ptr_write ++) = *(ptr_read ++);
}
}
void screenShot(int frame){
unsigned int br;
short width = frame == 0 ? 400 : 320;
short height = 240;
int frameOff = frame == 0 ? 0x1E6000 : 0x48F000; //<- Defaults
int length = frame == 0 ? 0x46500 : 0x38400;
memset(&handle, 0, 32);
fopen9(&handle, frame == 0 ? L"sdmc:/screen_top.bmp" : L"sdmc:/screen_bot.bmp", 6);
transpose(FCRAM+0xF80000, VRAM+frameOff, width, height, 3);
bmpHead[18] = frame == 0 ? 0x90 : 0x40;
fwrite9(&handle, &br, bmpHead, 0x36);
fwrite9(&handle, &br, FCRAM+0xF80000, length);
fclose9(&handle);
memset(VRAM+frameOff, 0xFF, 0x46500);
}
void patches(void){
//Change version string
for(int i = 0; i < 0x600000; i+=4){
if(strcomp((void*)0x27B00000 - i, (void*)L"Ver.", 4)) strcopy((void*)0x27B00000 - i, (void*)L"\uE024Rei", 4);
}
}
void thread(void){
while(1){
if(isPressed(BUTTON_SELECT | BUTTON_X)){
screenShot(TOP_FRAME);
screenShot(BOT_FRAME);
}
if(isPressed(BUTTON_START)){
memdump(L"sdmc:/AXIWRAM.bin", AXIWRAM, 0x00080000);
memdump(L"sdmc:/FCRAM.bin", FCRAM, 0x010000000);
}
patches();
}
__asm("SVC 0x09");
}

6
thread/source/thread.h Normal file
View File

@ -0,0 +1,6 @@
/*
* thread.h
* by Reisyukaku
*/
void thread(void);