Drop pre-A9LH support
This commit is contained in:
parent
ba88ec25f6
commit
bd62f033ab
9
.gitmodules
vendored
9
.gitmodules
vendored
@ -1,9 +0,0 @@
|
|||||||
[submodule "haxloader/CakeBrah"]
|
|
||||||
path = haxloader/CakeBrah
|
|
||||||
url = https://github.com/mid-kid/CakeBrah.git
|
|
||||||
[submodule "haxloader/CakeHax"]
|
|
||||||
path = haxloader/CakeHax
|
|
||||||
url = https://github.com/mid-kid/CakeHax.git
|
|
||||||
[submodule "haxloader/CakesROP"]
|
|
||||||
path = haxloader/CakesROP
|
|
||||||
url = https://github.com/mid-kid/CakesROP.git
|
|
8
Makefile
8
Makefile
@ -17,7 +17,6 @@ dir_injector := injector
|
|||||||
dir_exceptions := exceptions
|
dir_exceptions := exceptions
|
||||||
dir_arm9_exceptions := $(dir_exceptions)/arm9
|
dir_arm9_exceptions := $(dir_exceptions)/arm9
|
||||||
dir_arm11_exceptions := $(dir_exceptions)/arm11
|
dir_arm11_exceptions := $(dir_exceptions)/arm11
|
||||||
dir_haxloader := haxloader
|
|
||||||
dir_build := build
|
dir_build := build
|
||||||
dir_out := out
|
dir_out := out
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ define bin2o
|
|||||||
endef
|
endef
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: a9lh haxloader
|
all: a9lh
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: $(dir_out)/$(name)$(revision).7z
|
release: $(dir_out)/$(name)$(revision).7z
|
||||||
@ -45,13 +44,8 @@ release: $(dir_out)/$(name)$(revision).7z
|
|||||||
.PHONY: a9lh
|
.PHONY: a9lh
|
||||||
a9lh: $(dir_out)/arm9loaderhax.bin
|
a9lh: $(dir_out)/arm9loaderhax.bin
|
||||||
|
|
||||||
.PHONY: haxloader
|
|
||||||
haxloader: a9lh
|
|
||||||
@$(MAKE) name=$(name) -C $(dir_haxloader)
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@$(MAKE) -C $(dir_haxloader) clean
|
|
||||||
@$(MAKE) -C $(dir_loader) clean
|
@$(MAKE) -C $(dir_loader) clean
|
||||||
@$(MAKE) -C $(dir_arm9_exceptions) clean
|
@$(MAKE) -C $(dir_arm9_exceptions) clean
|
||||||
@$(MAKE) -C $(dir_arm11_exceptions) clean
|
@$(MAKE) -C $(dir_arm11_exceptions) clean
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 1efda4e89476d34aeb307e0acd7a8dbcd1344601
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 329212a8e09d4718e304cb9d94a0e10f66d9813d
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit b14debbd349c1990aab65716086c8d3809ce90bf
|
|
@ -1,74 +0,0 @@
|
|||||||
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
|
|
||||||
|
|
||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(DEVKITARM)/base_tools
|
|
||||||
|
|
||||||
dir_source := source
|
|
||||||
dir_diffs := diffs
|
|
||||||
dir_cakebrah := CakeBrah
|
|
||||||
dir_cakehax := CakeHax
|
|
||||||
dir_cakesrop := CakesROP
|
|
||||||
dir_build := build
|
|
||||||
dir_out := ../out
|
|
||||||
|
|
||||||
ASFLAGS := -mcpu=arm946e-s
|
|
||||||
CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -Wno-main -O2 -flto -ffast-math
|
|
||||||
LDFLAGS := -nostartfiles
|
|
||||||
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Aurora Wright/TuxSH" --no-print-directory
|
|
||||||
ROPFLAGS := DATNAME=$(name).dat DISPNAME=$(name) GRAPHICS=../graphics/
|
|
||||||
|
|
||||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
|
||||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
|
||||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: $(dir_out)/hax/3ds/$(name) $(dir_out)/menuhax/boot.3dsx $(dir_out)/mset-spider/$(name).dat $(dir_out)/mset/$(name).nds
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
@cd $(dir_cakebrah); git reset --hard
|
|
||||||
@$(MAKE) $(FLAGS) -C $(dir_cakebrah) clean
|
|
||||||
@$(MAKE) $(FLAGS) -C $(dir_cakehax) clean
|
|
||||||
@$(MAKE) $(ROPFLAGS) -C $(dir_cakesrop) clean
|
|
||||||
@rm -rf $(dir_build)
|
|
||||||
|
|
||||||
$(dir_out)/mset-spider/$(name).dat: $(dir_build)/main.bin
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
@$(MAKE) $(FLAGS) -C $(dir_cakehax) launcher
|
|
||||||
@dd if=$(dir_build)/main.bin of=$(dir_out)/$(name).dat bs=512 seek=144
|
|
||||||
@mv $(dir_out)/$(name).dat $@
|
|
||||||
|
|
||||||
$(dir_out)/hax/3ds/$(name):
|
|
||||||
@mkdir -p "$@"
|
|
||||||
@cd $(dir_cakebrah); patch -p1 < ../$(dir_diffs)/1.diff; $(MAKE) $(FLAGS); git reset --hard
|
|
||||||
@mv $(dir_out)/$(name).3dsx $(dir_out)/$(name).smdh $@
|
|
||||||
|
|
||||||
$(dir_out)/menuhax/boot.3dsx:
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
@cd $(dir_cakebrah); patch -p1 < ../$(dir_diffs)/1.diff; patch -p1 < ../$(dir_diffs)/2.diff; $(MAKE) $(FLAGS); git reset --hard
|
|
||||||
@mv $(dir_out)/$(name).3dsx $@
|
|
||||||
@rm $(dir_out)/$(name).smdh
|
|
||||||
|
|
||||||
$(dir_out)/mset/$(name).nds:
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
@$(MAKE) $(ROPFLAGS) -C $(dir_cakesrop)
|
|
||||||
@mv $(dir_cakesrop)/CakesROP.nds $@
|
|
||||||
|
|
||||||
$(dir_build)/main.bin: $(dir_build)/main.elf
|
|
||||||
$(OBJCOPY) -S -O binary $< $@
|
|
||||||
|
|
||||||
$(dir_build)/main.elf: $(objects) ../$(dir_build)/loader.bin.o
|
|
||||||
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
|
|
||||||
|
|
||||||
$(dir_build)/memory.o: CFLAGS += -O3
|
|
||||||
|
|
||||||
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
|
||||||
|
|
||||||
$(dir_build)/%.o: $(dir_source)/%.s
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
$(COMPILE.s) $(OUTPUT_OPTION) $<
|
|
@ -1,123 +0,0 @@
|
|||||||
diff -uNr a/include/brahma.h b/include/brahma.h
|
|
||||||
--- a/include/brahma.h 2016-09-26 16:05:36.363067000 +0200
|
|
||||||
+++ b/include/brahma.h 2016-09-26 21:35:14.800519000 +0200
|
|
||||||
@@ -4,7 +4,7 @@
|
|
||||||
|
|
||||||
u32 brahma_init (void);
|
|
||||||
u32 brahma_exit (void);
|
|
||||||
-s32 load_arm9_payload_offset (char *filename, u32 offset, u32 max_psize);
|
|
||||||
+s32 load_arm9_payload_offset (void);
|
|
||||||
s32 load_arm9_payload_from_mem (u8* data, u32 dsize);
|
|
||||||
void redirect_codeflow (u32 *dst_addr, u32 *src_addr);
|
|
||||||
s32 map_arm9_payload (void);
|
|
||||||
@@ -13,8 +13,6 @@
|
|
||||||
s32 get_exploit_data (struct exploit_data *data);
|
|
||||||
s32 firm_reboot ();
|
|
||||||
|
|
||||||
-#define load_arm9_payload(filename) load_arm9_payload_offset(filename, 0, 0)
|
|
||||||
-
|
|
||||||
#define BRAHMA_NETWORK_PORT 80
|
|
||||||
|
|
||||||
#define ARM_JUMPOUT 0xE51FF004 // LDR PC, [PC, -#04]
|
|
||||||
diff -uNr a/source/brahma.c b/source/brahma.c
|
|
||||||
--- a/source/brahma.c 2016-09-26 16:05:36.363067000 +0200
|
|
||||||
+++ b/source/brahma.c 2016-09-26 21:37:58.660516468 +0200
|
|
||||||
@@ -179,39 +179,54 @@
|
|
||||||
return g_ext_arm9_loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* reads ARM9 payload from a given path.
|
|
||||||
- filename: full path of payload
|
|
||||||
- offset: offset of the payload in the file
|
|
||||||
- max_psize: the maximum size of the payload that should be loaded (if 0, ARM9_MAX_PAYLOAD_SIZE. Should be smaller than ARM9_MAX_PAYLOAD_SIZE)
|
|
||||||
+/* reads Luma payload
|
|
||||||
returns: 0 on failure, 1 on success */
|
|
||||||
-s32 load_arm9_payload_offset (char *filename, u32 offset, u32 max_psize) {
|
|
||||||
+s32 load_arm9_payload_offset (void) {
|
|
||||||
s32 result = 0;
|
|
||||||
u32 fsize = 0;
|
|
||||||
u32 psize = 0;
|
|
||||||
+ bool use_default = true;
|
|
||||||
+ FILE *f;
|
|
||||||
|
|
||||||
- if (max_psize == 0 || max_psize > ARM9_PAYLOAD_MAX_SIZE)
|
|
||||||
- max_psize = ARM9_PAYLOAD_MAX_SIZE;
|
|
||||||
+ FILE *p = fopen("/luma/path.txt", "r");
|
|
||||||
|
|
||||||
- if (!filename)
|
|
||||||
- return result;
|
|
||||||
+ if (p) {
|
|
||||||
+ fseek(p , 0, SEEK_END);
|
|
||||||
+ psize = ftell(p);
|
|
||||||
+ if (psize > 5 && psize < 58) {
|
|
||||||
+ char path[57];
|
|
||||||
+
|
|
||||||
+ fseek(p, 0, SEEK_SET);
|
|
||||||
+ u32 bytes_read = fread(path, 1, psize, p);
|
|
||||||
+
|
|
||||||
+ if (bytes_read == psize) {
|
|
||||||
+ if (path[psize - 1] == 0xA) psize--;
|
|
||||||
+ if (path[psize - 1] == 0xD) psize--;
|
|
||||||
+ if (psize > 5 && psize < 56 && path[0] == '/' && memcmp(path + psize - 4, ".bin", 4)) {
|
|
||||||
+ path[psize] = 0;
|
|
||||||
+ f = fopen(path, "rb");
|
|
||||||
+ if (f) use_default = false;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ fclose(p);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (use_default) f = fopen("/arm9loaderhax.bin", "rb");
|
|
||||||
|
|
||||||
- FILE *f = fopen(filename, "rb");
|
|
||||||
if (f) {
|
|
||||||
- fseek(f , 0, SEEK_END);
|
|
||||||
+ fseek(f, 0, SEEK_END);
|
|
||||||
fsize = ftell(f);
|
|
||||||
|
|
||||||
- if (offset < fsize) {
|
|
||||||
- psize = fsize - offset;
|
|
||||||
- if (psize > max_psize)
|
|
||||||
- psize = max_psize;
|
|
||||||
-
|
|
||||||
- g_ext_arm9_size = psize;
|
|
||||||
-
|
|
||||||
- fseek(f, offset, SEEK_SET);
|
|
||||||
- if (psize >= 8) {
|
|
||||||
- u32 bytes_read = fread(g_ext_arm9_buf, 1, psize, f);
|
|
||||||
- result = (g_ext_arm9_loaded = (bytes_read == psize));
|
|
||||||
- }
|
|
||||||
+ if (fsize > ARM9_PAYLOAD_MAX_SIZE)
|
|
||||||
+ fsize = ARM9_PAYLOAD_MAX_SIZE;
|
|
||||||
+
|
|
||||||
+ g_ext_arm9_size = fsize;
|
|
||||||
+
|
|
||||||
+ fseek(f, 0, SEEK_SET);
|
|
||||||
+ if (fsize >= 8) {
|
|
||||||
+ u32 bytes_read = fread(g_ext_arm9_buf, 1, fsize, f);
|
|
||||||
+ result = (g_ext_arm9_loaded = (bytes_read == fsize));
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
diff -uNr a/source/main.c b/source/main.c
|
|
||||||
--- a/source/main.c 2016-09-26 16:05:36.363067000 +0200
|
|
||||||
+++ b/source/main.c 2016-09-26 21:40:35.202513018 +0200
|
|
||||||
@@ -38,7 +38,7 @@
|
|
||||||
|
|
||||||
int main (void) {
|
|
||||||
if (brahma_init()) {
|
|
||||||
- if (load_arm9_payload_offset("/" LAUNCHER_PATH, 0x12000, 0x10000) != 1)
|
|
||||||
+ if (load_arm9_payload_offset() != 1)
|
|
||||||
goto error;
|
|
||||||
firm_reboot();
|
|
||||||
brahma_exit();
|
|
||||||
@@ -50,7 +50,7 @@
|
|
||||||
error:
|
|
||||||
gfxInitDefault();
|
|
||||||
consoleInit(GFX_BOTTOM, NULL);
|
|
||||||
- printf("An error occurred while loading the payload.\nMake sure your launcher is located at:\n/" LAUNCHER_PATH);
|
|
||||||
+ printf("An error occurred while loading the payload.");
|
|
||||||
wait_any_key();
|
|
||||||
|
|
||||||
gfxExit();
|
|
@ -1,11 +0,0 @@
|
|||||||
diff -uNr a/source/main.c b/source/main.c
|
|
||||||
--- a/source/main.c 2016-09-11 01:04:25.665231884 +0200
|
|
||||||
+++ b/source/main.c 2016-09-14 12:36:28.601439550 +0200
|
|
||||||
@@ -37,6 +37,7 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (void) {
|
|
||||||
+ svcSleepThread(2500 * 1000000ULL);
|
|
||||||
if (brahma_init()) {
|
|
||||||
if (load_arm9_payload_offset() != 1)
|
|
||||||
goto error;
|
|
@ -1,11 +0,0 @@
|
|||||||
-W3
|
|
||||||
# disable alpha and set opaque bit for all pixels
|
|
||||||
-gT!
|
|
||||||
|
|
||||||
# use lz77 compression
|
|
||||||
-gzl
|
|
||||||
|
|
||||||
# 16 bit bitmap
|
|
||||||
-gB16
|
|
||||||
|
|
||||||
-gb
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.6 KiB |
@ -1,14 +0,0 @@
|
|||||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
|
||||||
OUTPUT_ARCH(arm)
|
|
||||||
|
|
||||||
ENTRY(_start)
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
. = 0x23F00000;
|
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
|
||||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
/***
|
|
||||||
The following functions flush the data cache, then waits for all memory transfers to be finished.
|
|
||||||
The data cache and/or the instruction cache MUST be flushed before doing one of the following:
|
|
||||||
- rebooting
|
|
||||||
- powering down
|
|
||||||
- setting the ARM11 entrypoint to execute a function
|
|
||||||
- jumping to a payload
|
|
||||||
***/
|
|
||||||
|
|
||||||
void flushEntireDCache(void); //actually: "clean and flush"
|
|
||||||
void flushDCacheRange(void *startAddress, u32 size);
|
|
||||||
void flushEntireICache(void);
|
|
||||||
void flushICacheRange(void *startAddress, u32 size);
|
|
@ -1,89 +0,0 @@
|
|||||||
@ This file is part of Luma3DS
|
|
||||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
@
|
|
||||||
@ This program is free software: you can redistribute it and/or modify
|
|
||||||
@ it under the terms of the GNU General Public License as published by
|
|
||||||
@ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
@ (at your option) any later version.
|
|
||||||
@
|
|
||||||
@ This program is distributed in the hope that it will be useful,
|
|
||||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
@ GNU General Public License for more details.
|
|
||||||
@
|
|
||||||
@ You should have received a copy of the GNU General Public License
|
|
||||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
@
|
|
||||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
@ Notices displayed by works containing it.
|
|
||||||
|
|
||||||
.text
|
|
||||||
.arm
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
.global flushEntireDCache
|
|
||||||
.type flushEntireDCache, %function
|
|
||||||
flushEntireDCache:
|
|
||||||
@ Adapted from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0155a/ch03s03s05.html,
|
|
||||||
@ and https://github.com/gemarcano/libctr9_io/blob/master/src/ctr_system_ARM.c#L39 as well
|
|
||||||
@ Note: ARM's example is actually for a 8KB DCache (which is what the 3DS has)
|
|
||||||
|
|
||||||
@ Implemented in bootROM at address 0xffff0830
|
|
||||||
mov r1, #0 @ segment counter
|
|
||||||
outer_loop:
|
|
||||||
mov r0, #0 @ line counter
|
|
||||||
|
|
||||||
inner_loop:
|
|
||||||
orr r2, r1, r0 @ generate segment and line address
|
|
||||||
mcr p15, 0, r2, c7, c14, 2 @ clean and flush the line
|
|
||||||
add r0, #0x20 @ increment to next line
|
|
||||||
cmp r0, #0x400
|
|
||||||
bne inner_loop
|
|
||||||
|
|
||||||
add r1, #0x40000000
|
|
||||||
cmp r1, #0
|
|
||||||
bne outer_loop
|
|
||||||
|
|
||||||
mcr p15, 0, r1, c7, c10, 4 @ drain write buffer
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global flushDCacheRange
|
|
||||||
.type flushDCacheRange, %function
|
|
||||||
flushDCacheRange:
|
|
||||||
@ Implemented in bootROM at address 0xffff08a0
|
|
||||||
add r1, r0, r1 @ end address
|
|
||||||
bic r0, #0x1f @ align source address to cache line size (32 bytes)
|
|
||||||
|
|
||||||
flush_dcache_range_loop:
|
|
||||||
mcr p15, 0, r0, c7, c14, 1 @ clean and flush the line corresponding to the address r0 is holding
|
|
||||||
add r0, #0x20
|
|
||||||
cmp r0, r1
|
|
||||||
blo flush_dcache_range_loop
|
|
||||||
|
|
||||||
mov r0, #0
|
|
||||||
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global flushEntireICache
|
|
||||||
.type flushEntireICache, %function
|
|
||||||
flushEntireICache:
|
|
||||||
@ Implemented in bootROM at address 0xffff0ab4
|
|
||||||
mov r0, #0
|
|
||||||
mcr p15, 0, r0, c7, c5, 0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global flushICacheRange
|
|
||||||
.type flushICacheRange, %function
|
|
||||||
flushICacheRange:
|
|
||||||
@ Implemented in bootROM at address 0xffff0ac0
|
|
||||||
add r1, r0, r1 @ end address
|
|
||||||
bic r0, #0x1f @ align source address to cache line size (32 bytes)
|
|
||||||
|
|
||||||
flush_icache_range_loop:
|
|
||||||
mcr p15, 0, r0, c7, c5, 1 @ flush the line corresponding to the address r0 is holding
|
|
||||||
add r0, #0x20
|
|
||||||
cmp r0, r1
|
|
||||||
blo flush_icache_range_loop
|
|
||||||
|
|
||||||
bx lr
|
|
@ -1,288 +0,0 @@
|
|||||||
----------------------------------------------------------------------------
|
|
||||||
Revision history of FatFs module
|
|
||||||
----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
R0.00 (February 26, 2006)
|
|
||||||
|
|
||||||
Prototype.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.01 (April 29, 2006)
|
|
||||||
|
|
||||||
The first release.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 value on error.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 when 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)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.11a (September 05, 2015)
|
|
||||||
|
|
||||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
|
||||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
|
||||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
|
||||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
|
||||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.12 (April 12, 2016)
|
|
||||||
|
|
||||||
Added support for exFAT file system. (_FS_EXFAT)
|
|
||||||
Added f_expand(). (_USE_EXPAND)
|
|
||||||
Changed some members in FINFO structure and behavior of f_readdir().
|
|
||||||
Added an option _USE_CHMOD.
|
|
||||||
Removed an option _WORD_ACCESS.
|
|
||||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.12a (July 10, 2016)
|
|
||||||
|
|
||||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
|
||||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
|
||||||
f_forward() is available regardless of _FS_TINY.
|
|
||||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
|
||||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
|
||||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.12b (September 04, 2016)
|
|
||||||
|
|
||||||
Made f_rename() be able to rename objects with the same name but case.
|
|
||||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
|
||||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
|
||||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
|
||||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
|
||||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
|
||||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
|
||||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
R0.12c (March 04, 2017)
|
|
||||||
|
|
||||||
Improved write throughput at the fragmented file on the exFAT volume.
|
|
||||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
|
||||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
|
||||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
FatFs Module Source Files R0.12c
|
|
||||||
|
|
||||||
|
|
||||||
FILES
|
|
||||||
|
|
||||||
00readme.txt This file.
|
|
||||||
00history.txt Revision history.
|
|
||||||
ff.c FatFs module.
|
|
||||||
ffconf.h Configuration file of FatFs module.
|
|
||||||
ff.h Common include file for FatFs and application 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 modules.
|
|
||||||
|
|
||||||
|
|
||||||
Low level disk I/O module is not included in this archive because the FatFs
|
|
||||||
module is only a generic file system layer and it does not depend on any specific
|
|
||||||
storage device. You have to provide a low level disk I/O module written to
|
|
||||||
control the storage device that attached to the target system.
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* 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 */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return sdmmc_sdcard_init() ? RES_OK : RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* 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 */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return (!sdmmc_sdcard_readsectors(sector, count, buff)) ? RES_OK : RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if _USE_WRITE
|
|
||||||
DRESULT disk_write (
|
|
||||||
__attribute__((unused))
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
__attribute__((unused))
|
|
||||||
const BYTE *buff, /* Data to be written */
|
|
||||||
__attribute__((unused))
|
|
||||||
DWORD sector, /* Sector address in LBA */
|
|
||||||
__attribute__((unused))
|
|
||||||
UINT count /* Number of sectors to write */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
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
|
|
@ -1,80 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------/
|
|
||||||
/ 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
@ -1,361 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------/
|
|
||||||
/ FatFs - Generic FAT file system module R0.12c /
|
|
||||||
/-----------------------------------------------------------------------------/
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2017, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
|
||||||
/ source and binary forms, with or without modification, are permitted provided
|
|
||||||
/ that the following condition is met:
|
|
||||||
|
|
||||||
/ 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 68300 /* 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 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type of path name strings on FatFs API */
|
|
||||||
|
|
||||||
#if _LFN_UNICODE /* Unicode (UTF-16) string */
|
|
||||||
#if _USE_LFN == 0
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type of file size variables */
|
|
||||||
|
|
||||||
#if _FS_EXFAT
|
|
||||||
#if _USE_LFN == 0
|
|
||||||
#error LFN must be enabled when enable exFAT
|
|
||||||
#endif
|
|
||||||
typedef QWORD FSIZE_t;
|
|
||||||
#else
|
|
||||||
typedef DWORD FSIZE_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File system object structure (FATFS) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BYTE fs_type; /* File system type (0:N/A) */
|
|
||||||
BYTE drv; /* Physical drive number */
|
|
||||||
BYTE n_fats; /* Number of FATs (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) */
|
|
||||||
WORD csize; /* Cluster size [sectors] */
|
|
||||||
#if _MAX_SS != _MIN_SS
|
|
||||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
|
||||||
#endif
|
|
||||||
#if _USE_LFN != 0
|
|
||||||
WCHAR* lfnbuf; /* LFN working buffer */
|
|
||||||
#endif
|
|
||||||
#if _FS_EXFAT
|
|
||||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
|
|
||||||
#endif
|
|
||||||
#if _FS_REENTRANT
|
|
||||||
_SYNC_t sobj; /* Identifier of sync object */
|
|
||||||
#endif
|
|
||||||
#if !_FS_READONLY
|
|
||||||
DWORD last_clst; /* Last allocated cluster */
|
|
||||||
DWORD free_clst; /* Number of free clusters */
|
|
||||||
#endif
|
|
||||||
#if _FS_RPATH != 0
|
|
||||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
|
||||||
#if _FS_EXFAT
|
|
||||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
|
||||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
|
||||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
|
||||||
DWORD fsize; /* Size of an FAT [sectors] */
|
|
||||||
DWORD volbase; /* Volume base sector */
|
|
||||||
DWORD fatbase; /* FAT base sector */
|
|
||||||
DWORD dirbase; /* Root directory base sector/cluster */
|
|
||||||
DWORD database; /* Data base 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Object ID and allocation information (_FDID) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FATFS* fs; /* Pointer to the owner file system object */
|
|
||||||
WORD id; /* Owner file system mount ID */
|
|
||||||
BYTE attr; /* Object attribute */
|
|
||||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
|
|
||||||
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
|
|
||||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
|
||||||
#if _FS_EXFAT
|
|
||||||
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
|
|
||||||
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
|
|
||||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
|
||||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
|
||||||
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
|
|
||||||
#endif
|
|
||||||
#if _FS_LOCK != 0
|
|
||||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
|
||||||
#endif
|
|
||||||
} _FDID;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File object structure (FIL) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
|
||||||
BYTE flag; /* File status flags */
|
|
||||||
BYTE err; /* Abort flag (error code) */
|
|
||||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
|
||||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
|
||||||
DWORD sect; /* 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 open, set by application) */
|
|
||||||
#endif
|
|
||||||
#if !_FS_TINY
|
|
||||||
BYTE buf[_MAX_SS]; /* File private data read/write window */
|
|
||||||
#endif
|
|
||||||
} FIL;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Directory object structure (DIR) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_FDID obj; /* Object identifier */
|
|
||||||
DWORD dptr; /* Current read/write offset */
|
|
||||||
DWORD clust; /* Current cluster */
|
|
||||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
|
||||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
|
||||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
|
||||||
#if _USE_LFN != 0
|
|
||||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
|
||||||
#endif
|
|
||||||
#if _USE_FIND
|
|
||||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
|
||||||
#endif
|
|
||||||
} DIR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File information structure (FILINFO) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FSIZE_t fsize; /* File size */
|
|
||||||
WORD fdate; /* Modified date */
|
|
||||||
WORD ftime; /* Modified time */
|
|
||||||
BYTE fattrib; /* File attribute */
|
|
||||||
#if _USE_LFN != 0
|
|
||||||
TCHAR altname[13]; /* Altenative file name */
|
|
||||||
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
|
|
||||||
#else
|
|
||||||
TCHAR fname[13]; /* File name */
|
|
||||||
#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 problem */
|
|
||||||
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_LOCK */
|
|
||||||
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 the file */
|
|
||||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
|
||||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
|
||||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
|
||||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the 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 a file/dir */
|
|
||||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a 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_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
|
||||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
|
||||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
|
||||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT 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)->obj.objsize))
|
|
||||||
#define f_error(fp) ((fp)->err)
|
|
||||||
#define f_tell(fp) ((fp)->fptr)
|
|
||||||
#define f_size(fp) ((fp)->obj.objsize)
|
|
||||||
#define f_rewind(fp) f_lseek((fp), 0)
|
|
||||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
|
||||||
#define f_rmdir(path) f_unlink(path)
|
|
||||||
|
|
||||||
#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 != 0 /* 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 mode and open method flags (3rd argument of f_open) */
|
|
||||||
#define FA_READ 0x01
|
|
||||||
#define FA_WRITE 0x02
|
|
||||||
#define FA_OPEN_EXISTING 0x00
|
|
||||||
#define FA_CREATE_NEW 0x04
|
|
||||||
#define FA_CREATE_ALWAYS 0x08
|
|
||||||
#define FA_OPEN_ALWAYS 0x10
|
|
||||||
#define FA_OPEN_APPEND 0x30
|
|
||||||
|
|
||||||
/* Fast seek controls (2nd argument of f_lseek) */
|
|
||||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
|
||||||
|
|
||||||
/* Format options (2nd argument of f_mkfs) */
|
|
||||||
#define FM_FAT 0x01
|
|
||||||
#define FM_FAT32 0x02
|
|
||||||
#define FM_EXFAT 0x04
|
|
||||||
#define FM_ANY 0x07
|
|
||||||
#define FM_SFD 0x08
|
|
||||||
|
|
||||||
/* Filesystem type (FATFS.fs_type) */
|
|
||||||
#define FS_FAT12 1
|
|
||||||
#define FS_FAT16 2
|
|
||||||
#define FS_FAT32 3
|
|
||||||
#define FS_EXFAT 4
|
|
||||||
|
|
||||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
|
||||||
#define AM_RDO 0x01 /* Read only */
|
|
||||||
#define AM_HID 0x02 /* Hidden */
|
|
||||||
#define AM_SYS 0x04 /* System */
|
|
||||||
#define AM_DIR 0x10 /* Directory */
|
|
||||||
#define AM_ARC 0x20 /* Archive */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _FATFS */
|
|
@ -1,268 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ FatFs - FAT file system module configuration file
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _FFCONF 68300 /* Revision ID */
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Function Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#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 3
|
|
||||||
/* 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_truncate() and f_rename()
|
|
||||||
/ 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 functions, f_findfirst() and
|
|
||||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_MKFS 0
|
|
||||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_FASTSEEK 0
|
|
||||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_EXPAND 0
|
|
||||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_CHMOD 0
|
|
||||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
|
||||||
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
|
|
||||||
|
|
||||||
|
|
||||||
#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) */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ 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 support of extended character. Non-LFN cfg. only)
|
|
||||||
/ 437 - U.S.
|
|
||||||
/ 720 - Arabic
|
|
||||||
/ 737 - Greek
|
|
||||||
/ 771 - KBL
|
|
||||||
/ 775 - Baltic
|
|
||||||
/ 850 - Latin 1
|
|
||||||
/ 852 - Latin 2
|
|
||||||
/ 855 - Cyrillic
|
|
||||||
/ 857 - Turkish
|
|
||||||
/ 860 - Portuguese
|
|
||||||
/ 861 - Icelandic
|
|
||||||
/ 862 - Hebrew
|
|
||||||
/ 863 - Canadian French
|
|
||||||
/ 864 - Arabic
|
|
||||||
/ 865 - Nordic
|
|
||||||
/ 866 - Russian
|
|
||||||
/ 869 - Greek 2
|
|
||||||
/ 932 - Japanese (DBCS)
|
|
||||||
/ 936 - Simplified Chinese (DBCS)
|
|
||||||
/ 949 - Korean (DBCS)
|
|
||||||
/ 950 - Traditional Chinese (DBCS)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_LFN 2
|
|
||||||
#define _MAX_LFN 255
|
|
||||||
/* The _USE_LFN switches the support of long file name (LFN).
|
|
||||||
/
|
|
||||||
/ 0: Disable support of LFN. _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.
|
|
||||||
/
|
|
||||||
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
|
|
||||||
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
|
|
||||||
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
|
|
||||||
/ It should be set 255 to support full featured LFN operations.
|
|
||||||
/ 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:UTF-16)
|
|
||||||
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
|
|
||||||
/ This option also affects behavior of string I/O functions. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _STRF_ENCODE 3
|
|
||||||
/* When _LFN_UNICODE == 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
|
|
||||||
/
|
|
||||||
/ This option has no effect when _LFN_UNICODE == 0. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_RPATH 0
|
|
||||||
/* This option configures support of relative path.
|
|
||||||
/
|
|
||||||
/ 0: Disable relative path and remove related functions.
|
|
||||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
|
||||||
/ 2: f_getcwd() function is available in addition to 1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Drive/Volume Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define _VOLUMES 1
|
|
||||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
|
||||||
|
|
||||||
|
|
||||||
#define _STR_VOLUME_ID 0
|
|
||||||
#define _VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
|
||||||
/* _STR_VOLUME_ID switches string support of volume ID.
|
|
||||||
/ 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 support of multi-partition on a physical drive.
|
|
||||||
/ 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 is enabled (1), each logical drive number can be 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, generic memory card 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 needs to be implemented to
|
|
||||||
/ the disk_ioctl() function. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _USE_TRIM 0
|
|
||||||
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
|
|
||||||
/ To enable Trim function, 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_TINY 0
|
|
||||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
|
||||||
/ At the tiny configuration, size of file object (FIL) is shrinked _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_EXFAT 0
|
|
||||||
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
|
|
||||||
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
|
|
||||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_NORTC 1
|
|
||||||
#define _NORTC_MON 1
|
|
||||||
#define _NORTC_MDAY 1
|
|
||||||
#define _NORTC_YEAR 2017
|
|
||||||
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
|
|
||||||
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
|
|
||||||
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
|
|
||||||
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
|
|
||||||
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
|
|
||||||
/ added to the project to get current time form real-time clock. _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 option _FS_LOCK switches file lock function 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 function. To avoid volume corruption, application program
|
|
||||||
/ should avoid illegal open, remove and rename to the open objects.
|
|
||||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
|
||||||
/ can be opened simultaneously under file lock control. Note that the file
|
|
||||||
/ lock control is independent of re-entrancy. */
|
|
||||||
|
|
||||||
|
|
||||||
#define _FS_REENTRANT 0
|
|
||||||
#define _FS_TIMEOUT 1000
|
|
||||||
#define _SYNC_t HANDLE
|
|
||||||
/* The option _FS_REENTRANT 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 function.
|
|
||||||
/
|
|
||||||
/ 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.h. */
|
|
||||||
|
|
||||||
/* #include <windows.h> // O/S definitions */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--- End of configuration options ---*/
|
|
@ -1,38 +0,0 @@
|
|||||||
/*-------------------------------------------*/
|
|
||||||
/* Integer type definitions for FatFs module */
|
|
||||||
/*-------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _FF_INTEGER
|
|
||||||
#define _FF_INTEGER
|
|
||||||
|
|
||||||
#ifdef _WIN32 /* FatFs development platform */
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
typedef unsigned __int64 QWORD;
|
|
||||||
|
|
||||||
|
|
||||||
#else /* Embedded platform */
|
|
||||||
|
|
||||||
/* These types MUST be 16-bit or 32-bit */
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
|
|
||||||
/* 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 32-bit */
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
|
|
||||||
typedef unsigned long long QWORD;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,388 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */
|
|
||||||
/* (SBCS code pages) */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* 437 U.S.
|
|
||||||
/ 720 Arabic
|
|
||||||
/ 737 Greek
|
|
||||||
/ 771 KBL
|
|
||||||
/ 775 Baltic
|
|
||||||
/ 850 Latin 1
|
|
||||||
/ 852 Latin 2
|
|
||||||
/ 855 Cyrillic
|
|
||||||
/ 857 Turkish
|
|
||||||
/ 860 Portuguese
|
|
||||||
/ 861 Icelandic
|
|
||||||
/ 862 Hebrew
|
|
||||||
/ 863 Canadian French
|
|
||||||
/ 864 Arabic
|
|
||||||
/ 865 Nordic
|
|
||||||
/ 866 Russian
|
|
||||||
/ 869 Greek 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../ff.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if _CODE_PAGE == 437
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 720
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
|
||||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
|
||||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 737
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
|
||||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
|
||||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
|
||||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 771
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
|
||||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
|
||||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D,
|
|
||||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
|
||||||
0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 775
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
|
||||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
|
||||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
|
||||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 850
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
|
||||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 852
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
|
||||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
|
||||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 855
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
|
||||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
|
||||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
|
||||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
|
||||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 857
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
|
||||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
|
||||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
|
||||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 860
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
|
|
||||||
0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 861
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
|
|
||||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 862
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
|
||||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 863
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0,
|
|
||||||
0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
|
|
||||||
0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 864
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518,
|
|
||||||
0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000,
|
|
||||||
0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5,
|
|
||||||
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F,
|
|
||||||
0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9,
|
|
||||||
0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9,
|
|
||||||
0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1,
|
|
||||||
0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 865
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
||||||
0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
|
|
||||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
||||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 866
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
|
||||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
|
||||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
||||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
||||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
|
||||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif _CODE_PAGE == 869
|
|
||||||
#define _TBLDEF 1
|
|
||||||
static
|
|
||||||
const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */
|
|
||||||
0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389,
|
|
||||||
0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF,
|
|
||||||
0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB,
|
|
||||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510,
|
|
||||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3,
|
|
||||||
0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580,
|
|
||||||
0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384,
|
|
||||||
0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if !_TBLDEF || !_USE_LFN
|
|
||||||
#error This file is not needed at current configuration. Remove from the project.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
|
||||||
WCHAR chr, /* Character code to be converted */
|
|
||||||
UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
WCHAR c;
|
|
||||||
|
|
||||||
|
|
||||||
if (chr < 0x80) { /* ASCII */
|
|
||||||
c = chr;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (dir) { /* OEM code to Unicode */
|
|
||||||
c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80];
|
|
||||||
|
|
||||||
} else { /* Unicode to OEM code */
|
|
||||||
for (c = 0; c < 0x80; c++) {
|
|
||||||
if (chr == Tbl[c]) break;
|
|
||||||
}
|
|
||||||
c = (c + 0x80) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WCHAR ff_wtoupper ( /* Returns upper converted character */
|
|
||||||
WCHAR chr /* Unicode character to be upper converted (BMP only) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Compressed upper conversion table */
|
|
||||||
static const WCHAR cvt1[] = { /* U+0000 - U+0FFF */
|
|
||||||
/* Basic Latin */
|
|
||||||
0x0061,0x031A,
|
|
||||||
/* Latin-1 Supplement */
|
|
||||||
0x00E0,0x0317, 0x00F8,0x0307, 0x00FF,0x0001,0x0178,
|
|
||||||
/* Latin Extended-A */
|
|
||||||
0x0100,0x0130, 0x0132,0x0106, 0x0139,0x0110, 0x014A,0x012E, 0x0179,0x0106,
|
|
||||||
/* Latin Extended-B */
|
|
||||||
0x0180,0x004D,0x0243,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,0x0187,0x0189,0x018A,0x018B,0x018B,0x018D,0x018E,0x018F,0x0190,0x0191,0x0191,0x0193,0x0194,0x01F6,0x0196,0x0197,0x0198,0x0198,0x023D,0x019B,0x019C,0x019D,0x0220,0x019F,0x01A0,0x01A0,0x01A2,0x01A2,0x01A4,0x01A4,0x01A6,0x01A7,0x01A7,0x01A9,0x01AA,0x01AB,0x01AC,0x01AC,0x01AE,0x01AF,0x01AF,0x01B1,0x01B2,0x01B3,0x01B3,0x01B5,0x01B5,0x01B7,0x01B8,0x01B8,0x01BA,0x01BB,0x01BC,0x01BC,0x01BE,0x01F7,0x01C0,0x01C1,0x01C2,0x01C3,0x01C4,0x01C5,0x01C4,0x01C7,0x01C8,0x01C7,0x01CA,0x01CB,0x01CA,
|
|
||||||
0x01CD,0x0110, 0x01DD,0x0001,0x018E, 0x01DE,0x0112, 0x01F3,0x0003,0x01F1,0x01F4,0x01F4, 0x01F8,0x0128,
|
|
||||||
0x0222,0x0112, 0x023A,0x0009,0x2C65,0x023B,0x023B,0x023D,0x2C66,0x023F,0x0240,0x0241,0x0241, 0x0246,0x010A,
|
|
||||||
/* IPA Extensions */
|
|
||||||
0x0253,0x0040,0x0181,0x0186,0x0255,0x0189,0x018A,0x0258,0x018F,0x025A,0x0190,0x025C,0x025D,0x025E,0x025F,0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,0x0197,0x0196,0x026A,0x2C62,0x026C,0x026D,0x026E,0x019C,0x0270,0x0271,0x019D,0x0273,0x0274,0x019F,0x0276,0x0277,0x0278,0x0279,0x027A,0x027B,0x027C,0x2C64,0x027E,0x027F,0x01A6,0x0281,0x0282,0x01A9,0x0284,0x0285,0x0286,0x0287,0x01AE,0x0244,0x01B1,0x01B2,0x0245,0x028D,0x028E,0x028F,0x0290,0x0291,0x01B7,
|
|
||||||
/* Greek, Coptic */
|
|
||||||
0x037B,0x0003,0x03FD,0x03FE,0x03FF, 0x03AC,0x0004,0x0386,0x0388,0x0389,0x038A, 0x03B1,0x0311,
|
|
||||||
0x03C2,0x0002,0x03A3,0x03A3, 0x03C4,0x0308, 0x03CC,0x0003,0x038C,0x038E,0x038F, 0x03D8,0x0118,
|
|
||||||
0x03F2,0x000A,0x03F9,0x03F3,0x03F4,0x03F5,0x03F6,0x03F7,0x03F7,0x03F9,0x03FA,0x03FA,
|
|
||||||
/* Cyrillic */
|
|
||||||
0x0430,0x0320, 0x0450,0x0710, 0x0460,0x0122, 0x048A,0x0136, 0x04C1,0x010E, 0x04CF,0x0001,0x04C0, 0x04D0,0x0144,
|
|
||||||
/* Armenian */
|
|
||||||
0x0561,0x0426,
|
|
||||||
|
|
||||||
0x0000
|
|
||||||
};
|
|
||||||
static const WCHAR cvt2[] = { /* U+1000 - U+FFFF */
|
|
||||||
/* Phonetic Extensions */
|
|
||||||
0x1D7D,0x0001,0x2C63,
|
|
||||||
/* Latin Extended Additional */
|
|
||||||
0x1E00,0x0196, 0x1EA0,0x015A,
|
|
||||||
/* Greek Extended */
|
|
||||||
0x1F00,0x0608, 0x1F10,0x0606, 0x1F20,0x0608, 0x1F30,0x0608, 0x1F40,0x0606,
|
|
||||||
0x1F51,0x0007,0x1F59,0x1F52,0x1F5B,0x1F54,0x1F5D,0x1F56,0x1F5F, 0x1F60,0x0608,
|
|
||||||
0x1F70,0x000E,0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,
|
|
||||||
0x1F80,0x0608, 0x1F90,0x0608, 0x1FA0,0x0608, 0x1FB0,0x0004,0x1FB8,0x1FB9,0x1FB2,0x1FBC,
|
|
||||||
0x1FCC,0x0001,0x1FC3, 0x1FD0,0x0602, 0x1FE0,0x0602, 0x1FE5,0x0001,0x1FEC, 0x1FF2,0x0001,0x1FFC,
|
|
||||||
/* Letterlike Symbols */
|
|
||||||
0x214E,0x0001,0x2132,
|
|
||||||
/* Number forms */
|
|
||||||
0x2170,0x0210, 0x2184,0x0001,0x2183,
|
|
||||||
/* Enclosed Alphanumerics */
|
|
||||||
0x24D0,0x051A, 0x2C30,0x042F,
|
|
||||||
/* Latin Extended-C */
|
|
||||||
0x2C60,0x0102, 0x2C67,0x0106, 0x2C75,0x0102,
|
|
||||||
/* Coptic */
|
|
||||||
0x2C80,0x0164,
|
|
||||||
/* Georgian Supplement */
|
|
||||||
0x2D00,0x0826,
|
|
||||||
/* Full-width */
|
|
||||||
0xFF41,0x031A,
|
|
||||||
|
|
||||||
0x0000
|
|
||||||
};
|
|
||||||
const WCHAR *p;
|
|
||||||
WCHAR bc, nc, cmd;
|
|
||||||
|
|
||||||
|
|
||||||
p = chr < 0x1000 ? cvt1 : cvt2;
|
|
||||||
for (;;) {
|
|
||||||
bc = *p++; /* Get block base */
|
|
||||||
if (!bc || chr < bc) break;
|
|
||||||
nc = *p++; cmd = nc >> 8; nc &= 0xFF; /* Get processing command and block size */
|
|
||||||
if (chr < bc + nc) { /* In the block? */
|
|
||||||
switch (cmd) {
|
|
||||||
case 0: chr = p[chr - bc]; break; /* Table conversion */
|
|
||||||
case 1: chr -= (chr - bc) & 1; break; /* Case pairs */
|
|
||||||
case 2: chr -= 16; break; /* Shift -16 */
|
|
||||||
case 3: chr -= 32; break; /* Shift -32 */
|
|
||||||
case 4: chr -= 48; break; /* Shift -48 */
|
|
||||||
case 5: chr -= 26; break; /* Shift -26 */
|
|
||||||
case 6: chr += 8; break; /* Shift +8 */
|
|
||||||
case 7: chr -= 80; break; /* Shift -80 */
|
|
||||||
case 8: chr -= 0x1C60; break; /* Shift -0x1C60 */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!cmd) p += nc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chr;
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../../types.h"
|
|
||||||
|
|
||||||
void waitcycles(u32 us);
|
|
@ -1,16 +0,0 @@
|
|||||||
.text
|
|
||||||
.arm
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
.global waitcycles
|
|
||||||
.type waitcycles, %function
|
|
||||||
waitcycles:
|
|
||||||
push {r0-r2, lr}
|
|
||||||
str r0, [sp, #4]
|
|
||||||
waitcycles_loop:
|
|
||||||
ldr r3, [sp, #4]
|
|
||||||
subs r2, r3, #1
|
|
||||||
str r2, [sp, #4]
|
|
||||||
cmp r3, #0
|
|
||||||
bne waitcycles_loop
|
|
||||||
pop {r0-r2, pc}
|
|
@ -1,490 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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-2015, 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 "sdmmc.h"
|
|
||||||
#include "delay.h"
|
|
||||||
|
|
||||||
//static struct mmcdevice handleNAND;
|
|
||||||
static struct mmcdevice handleSD;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
mmcdevice *getMMCDevice(int drive)
|
|
||||||
{
|
|
||||||
if(drive == 0) return &handleNAND;
|
|
||||||
return &handleSD;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int geterror(struct mmcdevice *ctx)
|
|
||||||
{
|
|
||||||
return (int)((ctx->error << 29) >> 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((noinline)) sdmmc_send_command(struct mmcdevice *ctx, u32 cmd, u32 args)
|
|
||||||
{
|
|
||||||
u32 getSDRESP = (cmd << 15) >> 31;
|
|
||||||
u16 flags = (cmd << 15) >> 31;
|
|
||||||
const int readdata = cmd & 0x20000;
|
|
||||||
const int 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);
|
|
||||||
sdmmc_mask16(REG_DATACTL32, 0x1800, 0);
|
|
||||||
sdmmc_write16(REG_SDCMDARG0, args & 0xFFFF);
|
|
||||||
sdmmc_write16(REG_SDCMDARG1, args >> 16);
|
|
||||||
sdmmc_write16(REG_SDCMD, cmd & 0xFFFF);
|
|
||||||
|
|
||||||
u32 size = ctx->size;
|
|
||||||
u8 *rDataPtr = ctx->rData;
|
|
||||||
const u8 *tDataPtr = ctx->tData;
|
|
||||||
|
|
||||||
bool rUseBuf = rDataPtr != NULL;
|
|
||||||
bool tUseBuf = tDataPtr != NULL;
|
|
||||||
|
|
||||||
u16 status0 = 0;
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
vu16 status1 = sdmmc_read16(REG_SDSTATUS1);
|
|
||||||
vu16 ctl32 = sdmmc_read16(REG_DATACTL32);
|
|
||||||
if((ctl32 & 0x100))
|
|
||||||
{
|
|
||||||
if(readdata)
|
|
||||||
{
|
|
||||||
if(rUseBuf)
|
|
||||||
{
|
|
||||||
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_RXRDY, 0);
|
|
||||||
if(size > 0x1FF)
|
|
||||||
{
|
|
||||||
//Gabriel Marcano: This implementation doesn't assume alignment.
|
|
||||||
//I've removed the alignment check doen with former rUseBuf32 as a result
|
|
||||||
for(int i = 0; i < 0x200; i += 4)
|
|
||||||
{
|
|
||||||
u32 data = sdmmc_read32(REG_SDFIFO32);
|
|
||||||
*rDataPtr++ = data;
|
|
||||||
*rDataPtr++ = data >> 8;
|
|
||||||
*rDataPtr++ = data >> 16;
|
|
||||||
*rDataPtr++ = data >> 24;
|
|
||||||
}
|
|
||||||
size -= 0x200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sdmmc_mask16(REG_DATACTL32, 0x800, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!(ctl32 & 0x200))
|
|
||||||
{
|
|
||||||
if(writedata)
|
|
||||||
{
|
|
||||||
if(tUseBuf)
|
|
||||||
{
|
|
||||||
sdmmc_mask16(REG_SDSTATUS1, TMIO_STAT1_TXRQ, 0);
|
|
||||||
if(size > 0x1FF)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 0x200; i += 4)
|
|
||||||
{
|
|
||||||
u32 data = *tDataPtr++;
|
|
||||||
data |= (u32)*tDataPtr++ << 8;
|
|
||||||
data |= (u32)*tDataPtr++ << 16;
|
|
||||||
data |= (u32)*tDataPtr++ << 24;
|
|
||||||
sdmmc_write32(REG_SDFIFO32, data);
|
|
||||||
}
|
|
||||||
size -= 0x200;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sdmmc_mask16(REG_DATACTL32, 0x1000, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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] = (u32)(sdmmc_read16(REG_SDRESP0) | (sdmmc_read16(REG_SDRESP1) << 16));
|
|
||||||
ctx->ret[1] = (u32)(sdmmc_read16(REG_SDRESP2) | (sdmmc_read16(REG_SDRESP3) << 16));
|
|
||||||
ctx->ret[2] = (u32)(sdmmc_read16(REG_SDRESP4) | (sdmmc_read16(REG_SDRESP5) << 16));
|
|
||||||
ctx->ret[3] = (u32)(sdmmc_read16(REG_SDRESP6) | (sdmmc_read16(REG_SDRESP7) << 16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int __attribute__((noinline)) sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in)
|
|
||||||
{
|
|
||||||
if(handleSD.isSDHC == 0) sector_no <<= 9;
|
|
||||||
inittarget(&handleSD);
|
|
||||||
sdmmc_write16(REG_SDSTOP, 0x100);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT32, numsectors);
|
|
||||||
sdmmc_write16(REG_SDBLKLEN32, 0x200);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT, numsectors);
|
|
||||||
handleSD.tData = 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);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT32, numsectors);
|
|
||||||
sdmmc_write16(REG_SDBLKLEN32, 0x200);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT, numsectors);
|
|
||||||
handleSD.rData = 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);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT32, numsectors);
|
|
||||||
sdmmc_write16(REG_SDBLKLEN32, 0x200);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT, numsectors);
|
|
||||||
handleNAND.rData = 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, const u8 *in) //experimental
|
|
||||||
{
|
|
||||||
if(handleNAND.isSDHC == 0) sector_no <<= 9;
|
|
||||||
inittarget(&handleNAND);
|
|
||||||
sdmmc_write16(REG_SDSTOP, 0x100);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT32, numsectors);
|
|
||||||
sdmmc_write16(REG_SDBLKLEN32, 0x200);
|
|
||||||
sdmmc_write16(REG_SDBLKCOUNT, numsectors);
|
|
||||||
handleNAND.tData = in;
|
|
||||||
handleNAND.size = numsectors << 9;
|
|
||||||
sdmmc_send_command(&handleNAND, 0x52C19, sector_no);
|
|
||||||
inittarget(&handleSD);
|
|
||||||
return geterror(&handleNAND);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static u32 calcSDSize(u8 *csd, int type)
|
|
||||||
{
|
|
||||||
u32 result = 0;
|
|
||||||
if(type == -1) type = csd[14] >> 6;
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
u32 block_len = csd[9] & 0xF;
|
|
||||||
block_len = 1u << block_len;
|
|
||||||
u32 mult = (u32)((csd[4] >> 7) | ((csd[5] & 3) << 1));
|
|
||||||
mult = 1u << (mult + 2);
|
|
||||||
result = csd[8] & 3;
|
|
||||||
result = (result << 8) | csd[7];
|
|
||||||
result = (result << 2) | (csd[6] >> 6);
|
|
||||||
result = (result + 1) * mult * block_len / 512;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
result = csd[7] & 0x3F;
|
|
||||||
result = (result << 8) | csd[6];
|
|
||||||
result = (result << 8) | csd[5];
|
|
||||||
result = (result + 1) * 1024;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break; //Do nothing otherwise FIXME perhaps return some error?
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InitSD()
|
|
||||||
{
|
|
||||||
*(vu16 *)0x10006100 &= 0xF7FFu; //SDDATACTL32
|
|
||||||
*(vu16 *)0x10006100 &= 0xEFFFu; //SDDATACTL32
|
|
||||||
*(vu16 *)0x10006100 |= 0x402u; //SDDATACTL32
|
|
||||||
*(vu16 *)0x100060D8 = (*(vu16 *)0x100060D8 & 0xFFDD) | 2;
|
|
||||||
*(vu16 *)0x10006100 &= 0xFFFFu; //SDDATACTL32
|
|
||||||
*(vu16 *)0x100060D8 &= 0xFFDFu; //SDDATACTL
|
|
||||||
*(vu16 *)0x10006104 = 512; //SDBLKLEN32
|
|
||||||
*(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
|
|
||||||
*(vu16 *)0x10006024 = 0x20;
|
|
||||||
*(vu16 *)0x10006028 = 0x40EE;
|
|
||||||
*(vu16 *)0x10006002 &= 0xFFFCu; ////SDPORTSEL
|
|
||||||
*(vu16 *)0x10006026 = 512; //SDBLKLEN
|
|
||||||
*(vu16 *)0x10006008 = 0; //SDSTOP
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static int Nand_Init()
|
|
||||||
{
|
|
||||||
//NAND
|
|
||||||
handleNAND.isSDHC = 0;
|
|
||||||
handleNAND.SDOPT = 0;
|
|
||||||
handleNAND.res = 0;
|
|
||||||
handleNAND.initarg = 1;
|
|
||||||
handleNAND.clk = 0x80;
|
|
||||||
handleNAND.devicenumber = 1;
|
|
||||||
|
|
||||||
inittarget(&handleNAND);
|
|
||||||
waitcycles(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;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int SD_Init()
|
|
||||||
{
|
|
||||||
//SD
|
|
||||||
handleSD.isSDHC = 0;
|
|
||||||
handleSD.SDOPT = 0;
|
|
||||||
handleSD.res = 0;
|
|
||||||
handleSD.initarg = 0;
|
|
||||||
handleSD.clk = 0x80;
|
|
||||||
handleSD.devicenumber = 0;
|
|
||||||
|
|
||||||
inittarget(&handleSD);
|
|
||||||
|
|
||||||
waitcycles(1u << 22); //Card needs a little bit of time to be detected, it seems FIXME test again to see what a good number is for the delay
|
|
||||||
|
|
||||||
//If not inserted
|
|
||||||
if(!(*((vu16 *)(SDMMC_BASE + REG_SDSTATUS0)) & TMIO_STAT0_SIGSTATE)) return 5;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0, 0);
|
|
||||||
sdmmc_send_command(&handleSD, 0x10408, 0x1AA);
|
|
||||||
u32 temp = (handleSD.error & 0x1) << 0x1E;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if(!((handleSD.ret[0] >> 30) & 1) || !temp)
|
|
||||||
temp2 = 0;
|
|
||||||
|
|
||||||
handleSD.isSDHC = temp2;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x10602, 0);
|
|
||||||
if((handleSD.error & 0x4)) return -1;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x10403, 0);
|
|
||||||
if((handleSD.error & 0x4)) return -2;
|
|
||||||
handleSD.initarg = handleSD.ret[0] >> 0x10;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x10609, handleSD.initarg << 0x10);
|
|
||||||
if((handleSD.error & 0x4)) return -3;
|
|
||||||
|
|
||||||
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 -4;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x10437, handleSD.initarg << 0x10);
|
|
||||||
if((handleSD.error & 0x4)) return -5;
|
|
||||||
|
|
||||||
handleSD.SDOPT = 1;
|
|
||||||
sdmmc_send_command(&handleSD, 0x10446, 0x2);
|
|
||||||
if((handleSD.error & 0x4)) return -6;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x1040D, handleSD.initarg << 0x10);
|
|
||||||
if((handleSD.error & 0x4)) return -7;
|
|
||||||
|
|
||||||
sdmmc_send_command(&handleSD, 0x10410, 0x200);
|
|
||||||
if((handleSD.error & 0x4)) return -8;
|
|
||||||
handleSD.clk |= 0x200;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void sdmmc_get_cid(bool isNand, u32 *info)
|
|
||||||
{
|
|
||||||
struct mmcdevice *device = isNand ? &handleNAND : &handleSD;
|
|
||||||
|
|
||||||
inittarget(device);
|
|
||||||
|
|
||||||
// use cmd7 to put sd card in standby mode
|
|
||||||
// CMD7
|
|
||||||
sdmmc_send_command(device, 0x10507, 0);
|
|
||||||
|
|
||||||
// get sd card info
|
|
||||||
// use cmd10 to read CID
|
|
||||||
sdmmc_send_command(device, 0x1060A, device->initarg << 0x10);
|
|
||||||
|
|
||||||
for(int i = 0; i < 4; ++i)
|
|
||||||
info[i] = device->ret[i];
|
|
||||||
|
|
||||||
// put sd card back to transfer mode
|
|
||||||
// CMD7
|
|
||||||
sdmmc_send_command(device, 0x10507, device->initarg << 0x10);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool sdmmc_sdcard_init()
|
|
||||||
{
|
|
||||||
InitSD();
|
|
||||||
//Nand_Init();
|
|
||||||
return SD_Init() == 0;
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../../types.h"
|
|
||||||
|
|
||||||
#define SDMMC_BASE 0x10006000
|
|
||||||
|
|
||||||
#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_DATACTL 0xD8
|
|
||||||
#define REG_SDRESET 0xE0
|
|
||||||
#define REG_SDPROTECTED 0xF6 //bit 0 determines if sd is protected or not?
|
|
||||||
|
|
||||||
#define REG_DATACTL32 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
|
|
||||||
|
|
||||||
#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 *rData;
|
|
||||||
const u8 *tData;
|
|
||||||
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;
|
|
||||||
|
|
||||||
bool sdmmc_sdcard_init();
|
|
||||||
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
|
||||||
//int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
|
||||||
//int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
|
||||||
//int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
|
||||||
//void sdmmc_get_cid(bool isNand, u32 *info);
|
|
||||||
//mmcdevice *getMMCDevice(int drive);
|
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Thanks to the everyone who contributed in the development of this file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "i2c.h"
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static const struct { u8 bus_id, reg_addr; } dev_data[] = {
|
|
||||||
{0, 0x4A}, {0, 0x7A}, {0, 0x78},
|
|
||||||
{1, 0x4A}, {1, 0x78}, {1, 0x2C},
|
|
||||||
{1, 0x2E}, {1, 0x40}, {1, 0x44},
|
|
||||||
{2, 0xD6}, {2, 0xD0}, {2, 0xD2},
|
|
||||||
{2, 0xA4}, {2, 0x9A}, {2, 0xA0},
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline u8 i2cGetDeviceBusId(u8 device_id)
|
|
||||||
{
|
|
||||||
return dev_data[device_id].bus_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u8 i2cGetDeviceRegAddr(u8 device_id)
|
|
||||||
{
|
|
||||||
return dev_data[device_id].reg_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static vu8 *reg_data_addrs[] = {
|
|
||||||
(vu8 *)(I2C1_REG_OFF + I2C_REG_DATA),
|
|
||||||
(vu8 *)(I2C2_REG_OFF + I2C_REG_DATA),
|
|
||||||
(vu8 *)(I2C3_REG_OFF + I2C_REG_DATA),
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline vu8 *i2cGetDataReg(u8 bus_id)
|
|
||||||
{
|
|
||||||
return reg_data_addrs[bus_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static vu8 *reg_cnt_addrs[] = {
|
|
||||||
(vu8 *)(I2C1_REG_OFF + I2C_REG_CNT),
|
|
||||||
(vu8 *)(I2C2_REG_OFF + I2C_REG_CNT),
|
|
||||||
(vu8 *)(I2C3_REG_OFF + I2C_REG_CNT),
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline vu8 *i2cGetCntReg(u8 bus_id)
|
|
||||||
{
|
|
||||||
return reg_cnt_addrs[bus_id];
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static inline void i2cWaitBusy(u8 bus_id)
|
|
||||||
{
|
|
||||||
while (*i2cGetCntReg(bus_id) & 0x80);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool i2cGetResult(u8 bus_id)
|
|
||||||
{
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
|
|
||||||
return (*i2cGetCntReg(bus_id) >> 4) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void i2cStop(u8 bus_id, u8 arg0)
|
|
||||||
{
|
|
||||||
*i2cGetCntReg(bus_id) = (arg0 << 5) | 0xC0;
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
*i2cGetCntReg(bus_id) = 0xC5;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static bool i2cSelectDevice(u8 bus_id, u8 dev_reg)
|
|
||||||
{
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
*i2cGetDataReg(bus_id) = dev_reg;
|
|
||||||
*i2cGetCntReg(bus_id) = 0xC2;
|
|
||||||
|
|
||||||
return i2cGetResult(bus_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool i2cSelectRegister(u8 bus_id, u8 reg)
|
|
||||||
{
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
*i2cGetDataReg(bus_id) = reg;
|
|
||||||
*i2cGetCntReg(bus_id) = 0xC0;
|
|
||||||
|
|
||||||
return i2cGetResult(bus_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data)
|
|
||||||
{
|
|
||||||
u8 bus_id = i2cGetDeviceBusId(dev_id),
|
|
||||||
dev_addr = i2cGetDeviceRegAddr(dev_id);
|
|
||||||
|
|
||||||
for(u32 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if(i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg))
|
|
||||||
{
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
*i2cGetDataReg(bus_id) = data;
|
|
||||||
*i2cGetCntReg(bus_id) = 0xC1;
|
|
||||||
i2cStop(bus_id, 0);
|
|
||||||
|
|
||||||
if(i2cGetResult(bus_id)) return true;
|
|
||||||
}
|
|
||||||
*i2cGetCntReg(bus_id) = 0xC5;
|
|
||||||
i2cWaitBusy(bus_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Thanks to the everyone who contributed in the development of this file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define I2C1_REG_OFF 0x10161000
|
|
||||||
#define I2C2_REG_OFF 0x10144000
|
|
||||||
#define I2C3_REG_OFF 0x10148000
|
|
||||||
|
|
||||||
#define I2C_REG_DATA 0
|
|
||||||
#define I2C_REG_CNT 1
|
|
||||||
#define I2C_REG_CNTEX 2
|
|
||||||
#define I2C_REG_SCL 4
|
|
||||||
|
|
||||||
#define I2C_DEV_MCU 3
|
|
||||||
#define I2C_DEV_GYRO 10
|
|
||||||
#define I2C_DEV_IR 13
|
|
||||||
|
|
||||||
bool i2cWriteRegister(u8 dev_id, u8 reg, u8 data);
|
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
#include "cache.h"
|
|
||||||
#include "i2c.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "fatfs/ff.h"
|
|
||||||
#include "../../build/bundled.h"
|
|
||||||
|
|
||||||
static FATFS fs;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
if(f_mount(&fs, "0:", 0) == FR_OK)
|
|
||||||
{
|
|
||||||
FIL pathFile,
|
|
||||||
payload;
|
|
||||||
bool foundPayload = false;
|
|
||||||
|
|
||||||
if(f_open(&pathFile, "luma/path.txt", FA_READ) == FR_OK)
|
|
||||||
{
|
|
||||||
u32 pathSize = f_size(&pathFile);
|
|
||||||
|
|
||||||
if(pathSize > 5 && pathSize < 58)
|
|
||||||
{
|
|
||||||
char path[57];
|
|
||||||
unsigned int read;
|
|
||||||
f_read(&pathFile, path, pathSize, &read);
|
|
||||||
if(path[pathSize - 1] == 0xA) pathSize--;
|
|
||||||
if(path[pathSize - 1] == 0xD) pathSize--;
|
|
||||||
|
|
||||||
if(pathSize > 5 && pathSize < 56 && path[0] == '/' && memcmp(path + pathSize - 4, ".bin", 4) == 0)
|
|
||||||
{
|
|
||||||
path[pathSize] = 0;
|
|
||||||
foundPayload = f_open(&payload, path, FA_READ) == FR_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f_close(&pathFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!foundPayload) foundPayload = f_open(&payload, "arm9loaderhax.bin", FA_READ) == FR_OK;
|
|
||||||
|
|
||||||
if(foundPayload)
|
|
||||||
{
|
|
||||||
u32 *loaderAddress = (u32 *)0x24FFFE00;
|
|
||||||
void *payloadAddress = (void *)0x24F00000;
|
|
||||||
u32 payloadSize = f_size(&payload);
|
|
||||||
|
|
||||||
memcpy(loaderAddress, loader_bin, loader_bin_size);
|
|
||||||
loaderAddress[1] = payloadSize;
|
|
||||||
|
|
||||||
unsigned int read;
|
|
||||||
f_read(&payload, payloadAddress, payloadSize, &read);
|
|
||||||
f_close(&payload);
|
|
||||||
|
|
||||||
if((u32)read == payloadSize)
|
|
||||||
{
|
|
||||||
flushDCacheRange(loaderAddress, loader_bin_size);
|
|
||||||
flushICacheRange(loaderAddress, loader_bin_size);
|
|
||||||
|
|
||||||
((void (*)())loaderAddress)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Ensure that all memory transfers have completed and that the data cache has been flushed
|
|
||||||
flushEntireDCache();
|
|
||||||
|
|
||||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0);
|
|
||||||
while(true);
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* memcpy and memcmp adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
void memcpy(void *dest, const void *src, u32 size)
|
|
||||||
{
|
|
||||||
u8 *destc = (u8 *)dest;
|
|
||||||
const u8 *srcc = (const u8 *)src;
|
|
||||||
|
|
||||||
for(u32 i = 0; i < size; i++)
|
|
||||||
destc[i] = srcc[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
int memcmp(const void *buf1, const void *buf2, u32 size)
|
|
||||||
{
|
|
||||||
const u8 *buf1c = (const u8 *)buf1,
|
|
||||||
*buf2c = (const u8 *)buf2;
|
|
||||||
|
|
||||||
for(u32 i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
int cmp = buf1c[i] - buf2c[i];
|
|
||||||
if(cmp != 0) return cmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* memcpy and memcmp adapted from https://github.com/mid-kid/CakesForeveryWan/blob/557a8e8605ab3ee173af6497486e8f22c261d0e2/source/memfuncs.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
void memcpy(void *dest, const void *src, u32 size);
|
|
||||||
int memcmp(const void *buf1, const void *buf2, u32 size);
|
|
@ -1,87 +0,0 @@
|
|||||||
@ This file is part of Luma3DS
|
|
||||||
@ Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
@
|
|
||||||
@ This program is free software: you can redistribute it and/or modify
|
|
||||||
@ it under the terms of the GNU General Public License as published by
|
|
||||||
@ the Free Software Foundation, either version 3 of the License, or
|
|
||||||
@ (at your option) any later version.
|
|
||||||
@
|
|
||||||
@ This program is distributed in the hope that it will be useful,
|
|
||||||
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
@ GNU General Public License for more details.
|
|
||||||
@
|
|
||||||
@ You should have received a copy of the GNU General Public License
|
|
||||||
@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
@
|
|
||||||
@ Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
@ reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
@ Notices displayed by works containing it.
|
|
||||||
|
|
||||||
@ Thanks to the numerous people who took part in writing this file
|
|
||||||
|
|
||||||
.section .text.start
|
|
||||||
.align 4
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
@ Disable interrupts
|
|
||||||
mrs r0, cpsr
|
|
||||||
orr r0, #0x1C0
|
|
||||||
msr cpsr_cx, r0
|
|
||||||
|
|
||||||
@ Change the stack pointer
|
|
||||||
mov sp, #0x27000000
|
|
||||||
|
|
||||||
@ Disable caches / MPU
|
|
||||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
|
||||||
bic r0, #(1<<12) @ - instruction cache disable
|
|
||||||
bic r0, #(1<<2) @ - data cache disable
|
|
||||||
bic r0, #(1<<0) @ - mpu disable
|
|
||||||
mcr p15, 0, r0, c1, c0, 0 @ write control register
|
|
||||||
|
|
||||||
@ Flush caches
|
|
||||||
bl flushEntireDCache
|
|
||||||
bl flushEntireICache
|
|
||||||
|
|
||||||
@ Give read/write access to all the memory regions
|
|
||||||
ldr r0, =0x3333333
|
|
||||||
mcr p15, 0, r0, c5, c0, 2 @ write data access
|
|
||||||
mcr p15, 0, r0, c5, c0, 3 @ write instruction access
|
|
||||||
|
|
||||||
@ Set MPU permissions and cache settings
|
|
||||||
ldr r0, =0xFFFF001D @ ffff0000 32k | bootrom (unprotected part)
|
|
||||||
ldr r1, =0x01FF801D @ 01ff8000 32k | itcm
|
|
||||||
ldr r2, =0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS)
|
|
||||||
ldr r3, =0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB)
|
|
||||||
ldr r4, =0x20000037 @ 20000000 256M | fcram (O3DS / N3DS)
|
|
||||||
ldr r5, =0x1FF00027 @ 1FF00000 1M | dsp / axi wram
|
|
||||||
ldr r6, =0x1800002D @ 18000000 8M | vram (+ 2MB)
|
|
||||||
mov r7, #0
|
|
||||||
mov r8, #0x15
|
|
||||||
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, c3, c0, 0 @ Write bufferable 0, 2, 4
|
|
||||||
mcr p15, 0, r8, c2, c0, 0 @ Data cacheable 0, 2, 4
|
|
||||||
mcr p15, 0, r8, c2, c0, 1 @ Inst cacheable 0, 2, 4
|
|
||||||
|
|
||||||
@ Enable caches / MPU / ITCM
|
|
||||||
mrc p15, 0, r0, c1, c0, 0 @ read control register
|
|
||||||
orr r0, r0, #(1<<18) @ - ITCM enable
|
|
||||||
orr r0, r0, #(1<<13) @ - alternate exception vectors enable
|
|
||||||
orr r0, r0, #(1<<12) @ - instruction cache enable
|
|
||||||
orr r0, r0, #(1<<2) @ - data cache enable
|
|
||||||
orr r0, r0, #(1<<0) @ - mpu enable
|
|
||||||
mcr p15, 0, r0, c1, c0, 0 @ write control register
|
|
||||||
|
|
||||||
@ Fix mounting of SDMC
|
|
||||||
ldr r0, =0x10000020
|
|
||||||
mov r1, #0x340
|
|
||||||
str r1, [r0]
|
|
||||||
|
|
||||||
b main
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Luma3DS
|
|
||||||
* Copyright (C) 2016 Aurora Wright, TuxSH
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified
|
|
||||||
* reasonable legal notices or author attributions in that material or in the Appropriate Legal
|
|
||||||
* Notices displayed by works containing it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
//Common data types
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
typedef volatile u8 vu8;
|
|
||||||
typedef volatile u16 vu16;
|
|
||||||
typedef volatile u32 vu32;
|
|
||||||
typedef volatile u64 vu64;
|
|
@ -5,15 +5,14 @@
|
|||||||
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||||
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||||
|
|
||||||
#define CONFIG(a) (((info.config >> (a + 20)) & 1) != 0)
|
#define CONFIG(a) (((info.config >> (a + 17)) & 1) != 0)
|
||||||
#define MULTICONFIG(a) ((info.config >> (a * 2 + 8)) & 3)
|
#define MULTICONFIG(a) ((info.config >> (a * 2 + 7)) & 3)
|
||||||
#define BOOTCONFIG(a, b) ((info.config >> a) & b)
|
#define BOOTCONFIG(a, b) ((info.config >> a) & b)
|
||||||
#define LOADERFLAG(a) ((info.flags >> (a + 4)) & 1) != 0
|
#define LOADERFLAG(a) ((info.flags >> (a + 4)) & 1) != 0
|
||||||
|
|
||||||
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
||||||
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
||||||
#define BOOTCFG_A9LH BOOTCONFIG(6, 1)
|
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(6, 1)
|
||||||
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(7, 1)
|
|
||||||
|
|
||||||
enum multiOptions
|
enum multiOptions
|
||||||
{
|
{
|
||||||
@ -26,8 +25,8 @@ enum multiOptions
|
|||||||
|
|
||||||
enum singleOptions
|
enum singleOptions
|
||||||
{
|
{
|
||||||
AUTOBOOTSYS = 0,
|
AUTOBOOTEMU = 0,
|
||||||
USESYSFIRM,
|
USEEMUFIRM,
|
||||||
LOADEXTFIRMSANDMODULES,
|
LOADEXTFIRMSANDMODULES,
|
||||||
USECUSTOMPATH,
|
USECUSTOMPATH,
|
||||||
PATCHGAMES,
|
PATCHGAMES,
|
||||||
|
@ -55,11 +55,11 @@ bool readConfig(void)
|
|||||||
|
|
||||||
void writeConfig(bool isPayloadLaunch)
|
void writeConfig(bool isPayloadLaunch)
|
||||||
{
|
{
|
||||||
if(isPayloadLaunch) configData.config = (configData.config & 0xFFFFFF00) | (oldConfig & 0xFF);
|
if(isPayloadLaunch) configData.config = (configData.config & 0xFFFFFF80) | (oldConfig & 0x7F);
|
||||||
|
|
||||||
/* If the configuration is different from previously, overwrite it.
|
/* If the configuration is different from previously, overwrite it.
|
||||||
Just the no-forcing flag being set is not enough */
|
Just the no-forcing flag being set is not enough */
|
||||||
if(needConfig != CREATE_CONFIGURATION && (configData.config & 0xFFFFFF7F) == oldConfig) return;
|
if(needConfig != CREATE_CONFIGURATION && (configData.config & 0xFFFFFFBF) == oldConfig) return;
|
||||||
|
|
||||||
if(needConfig == CREATE_CONFIGURATION)
|
if(needConfig == CREATE_CONFIGURATION)
|
||||||
{
|
{
|
||||||
@ -81,8 +81,8 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
|
|||||||
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )",
|
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
|
const char *singleOptionsText[] = { "( ) Autoboot EmuNAND",
|
||||||
"( ) Use SysNAND FIRM if booting with R",
|
"( ) Use EmuNAND FIRM if booting with R",
|
||||||
"( ) Enable loading external FIRMs and modules",
|
"( ) Enable loading external FIRMs and modules",
|
||||||
"( ) Use custom path",
|
"( ) Use custom path",
|
||||||
"( ) Enable game patching",
|
"( ) Enable game patching",
|
||||||
@ -122,9 +122,9 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
|
|||||||
"'Clock+L2' can cause issues with some\n"
|
"'Clock+L2' can cause issues with some\n"
|
||||||
"games.",
|
"games.",
|
||||||
|
|
||||||
"If enabled, SysNAND will be launched\n"
|
"If enabled, an EmuNAND will be\n"
|
||||||
"on boot.\n\n"
|
"launched on boot.\n\n"
|
||||||
"Otherwise, an EmuNAND will.\n\n"
|
"Otherwise, SysNAND will.\n\n"
|
||||||
"Hold L on boot to switch NAND.\n\n"
|
"Hold L on boot to switch NAND.\n\n"
|
||||||
"To use a different EmuNAND from the\n"
|
"To use a different EmuNAND from the\n"
|
||||||
"default, hold a directional pad button\n"
|
"default, hold a directional pad button\n"
|
||||||
@ -132,10 +132,10 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
|
|||||||
"1/2/3/4).",
|
"1/2/3/4).",
|
||||||
|
|
||||||
"If enabled, when holding R on boot\n"
|
"If enabled, when holding R on boot\n"
|
||||||
"EmuNAND will be booted with the\n"
|
"SysNAND will be booted with the\n"
|
||||||
"SysNAND FIRM.\n\n"
|
"EmuNAND FIRM.\n\n"
|
||||||
"Otherwise, SysNAND will be booted\n"
|
"Otherwise, an EmuNAND will be booted\n"
|
||||||
"with an EmuNAND FIRM.\n\n"
|
"with the SysNAND FIRM.\n\n"
|
||||||
"To use a different EmuNAND from the\n"
|
"To use a different EmuNAND from the\n"
|
||||||
"default, hold a directional pad button\n"
|
"default, hold a directional pad button\n"
|
||||||
"(Up/Right/Down/Left equal EmuNANDs\n"
|
"(Up/Right/Down/Left equal EmuNANDs\n"
|
||||||
@ -388,13 +388,13 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Preserve the last-used boot options (first 9 bits)
|
//Preserve the last-used boot options (first 9 bits)
|
||||||
configData.config &= 0xFF;
|
configData.config &= 0x7F;
|
||||||
|
|
||||||
//Parse and write the new configuration
|
//Parse and write the new configuration
|
||||||
for(u32 i = 0; i < multiOptionsAmount; i++)
|
for(u32 i = 0; i < multiOptionsAmount; i++)
|
||||||
configData.config |= multiOptions[i].enabled << (i * 2 + 8);
|
configData.config |= multiOptions[i].enabled << (i * 2 + 7);
|
||||||
for(u32 i = 0; i < singleOptionsAmount; i++)
|
for(u32 i = 0; i < singleOptionsAmount; i++)
|
||||||
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 20);
|
configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 17);
|
||||||
|
|
||||||
u32 newPinMode = MULTICONFIG(PIN);
|
u32 newPinMode = MULTICONFIG(PIN);
|
||||||
|
|
||||||
|
@ -24,18 +24,17 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#define CONFIG(a) (((configData.config >> (a + 20)) & 1) != 0)
|
#define CONFIG(a) (((configData.config >> (a + 17)) & 1) != 0)
|
||||||
#define MULTICONFIG(a) ((configData.config >> (a * 2 + 8)) & 3)
|
#define MULTICONFIG(a) ((configData.config >> (a * 2 + 7)) & 3)
|
||||||
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)
|
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)
|
||||||
|
|
||||||
#define CONFIG_FILE "config.bin"
|
#define CONFIG_FILE "config.bin"
|
||||||
#define CONFIG_VERSIONMAJOR 1
|
#define CONFIG_VERSIONMAJOR 1
|
||||||
#define CONFIG_VERSIONMINOR 9
|
#define CONFIG_VERSIONMINOR 10
|
||||||
|
|
||||||
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
||||||
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
||||||
#define BOOTCFG_A9LH BOOTCONFIG(6, 1)
|
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(6, 1)
|
||||||
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(7, 1)
|
|
||||||
|
|
||||||
enum multiOptions
|
enum multiOptions
|
||||||
{
|
{
|
||||||
@ -48,8 +47,8 @@ enum multiOptions
|
|||||||
|
|
||||||
enum singleOptions
|
enum singleOptions
|
||||||
{
|
{
|
||||||
AUTOBOOTSYS = 0,
|
AUTOBOOTEMU = 0,
|
||||||
USESYSFIRM,
|
USEEMUFIRM,
|
||||||
LOADEXTFIRMSANDMODULES,
|
LOADEXTFIRMSANDMODULES,
|
||||||
USECUSTOMPATH,
|
USECUSTOMPATH,
|
||||||
PATCHGAMES,
|
PATCHGAMES,
|
||||||
|
@ -400,26 +400,6 @@ int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set6x7xKeys(void)
|
|
||||||
{
|
|
||||||
__attribute__((aligned(4))) const u8 keyX0x25s[2][AES_BLOCK_SIZE] = {
|
|
||||||
{0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3},
|
|
||||||
{0x81, 0x90, 0x7A, 0x4B, 0x6F, 0x1B, 0x47, 0x32, 0x3A, 0x67, 0x79, 0x74, 0xCE, 0x4A, 0xD7, 0x1B}
|
|
||||||
},
|
|
||||||
keyY0x2Fs[2][AES_BLOCK_SIZE] = {
|
|
||||||
{0xC3, 0x69, 0xBA, 0xA2, 0x1E, 0x18, 0x8A, 0x88, 0xA9, 0xAA, 0x94, 0xE5, 0x50, 0x6A, 0x9F, 0x16},
|
|
||||||
{0x73, 0x25, 0xC4, 0xEB, 0x14, 0x3A, 0x0D, 0x5F, 0x5D, 0xB6, 0xE5, 0xC5, 0x7A, 0x21, 0x95, 0xAC}
|
|
||||||
};
|
|
||||||
|
|
||||||
aes_setkey(0x25, keyX0x25s[ISDEVUNIT ? 1 : 0], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
aes_setkey(0x2F, keyY0x2Fs[ISDEVUNIT ? 1 : 0], AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
|
|
||||||
/* [3dbrew] The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function,
|
|
||||||
when non-zero it clears this block and continues to do the key generation.
|
|
||||||
Otherwise when this block was already all-zero, it immediately returns. */
|
|
||||||
memset32((void *)0x01FFCD00, 0, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool decryptExeFs(Cxi *cxi)
|
bool decryptExeFs(Cxi *cxi)
|
||||||
{
|
{
|
||||||
if(memcmp(cxi->ncch.magic, "NCCH", 4) != 0) return false;
|
if(memcmp(cxi->ncch.magic, "NCCH", 4) != 0) return false;
|
||||||
@ -590,7 +570,7 @@ void computePinHash(u8 *outbuf, const u8 *inbuf)
|
|||||||
|
|
||||||
void backupAndRestoreShaHash(bool isRestore)
|
void backupAndRestoreShaHash(bool isRestore)
|
||||||
{
|
{
|
||||||
if(!ISA9LH) return;
|
if(ISSIGHAX) return;
|
||||||
|
|
||||||
static bool didShaHashBackup = false;
|
static bool didShaHashBackup = false;
|
||||||
__attribute__((aligned(4))) static u8 shaHashBackup[SHA_256_HASH_SIZE];
|
__attribute__((aligned(4))) static u8 shaHashBackup[SHA_256_HASH_SIZE];
|
||||||
|
@ -110,7 +110,6 @@ extern FirmwareSource firmSource;
|
|||||||
void ctrNandInit(void);
|
void ctrNandInit(void);
|
||||||
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
|
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
|
||||||
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
|
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
|
||||||
void set6x7xKeys(void);
|
|
||||||
bool decryptExeFs(Cxi *cxi);
|
bool decryptExeFs(Cxi *cxi);
|
||||||
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);
|
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);
|
||||||
void kernel9Loader(Arm9Bin *arm9Section);
|
void kernel9Loader(Arm9Bin *arm9Section);
|
||||||
|
@ -113,7 +113,7 @@ u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStora
|
|||||||
return firmVersion;
|
return firmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lhInstalled, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers)
|
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers)
|
||||||
{
|
{
|
||||||
u8 *arm9Section = (u8 *)firm + firm->section[2].offset,
|
u8 *arm9Section = (u8 *)firm + firm->section[2].offset,
|
||||||
*arm11Section1 = (u8 *)firm + firm->section[1].offset;
|
*arm11Section1 = (u8 *)firm + firm->section[1].offset;
|
||||||
@ -124,9 +124,6 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
|
|||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801B01C;
|
firm->arm9Entry = (u8 *)0x801B01C;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sets the 7.x NCCH KeyX and the 6.x gamecard save data KeyY on >= 6.0 O3DS FIRMs, if not using A9LH
|
|
||||||
else if(!ISA9LH && !ISFIRMLAUNCH && firmVersion >= 0x29) set6x7xKeys();
|
|
||||||
|
|
||||||
//Find the Process9 .code location, size and memory address
|
//Find the Process9 .code location, size and memory address
|
||||||
u32 process9Size,
|
u32 process9Size,
|
||||||
@ -151,7 +148,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
|
|||||||
if(nandType != FIRMWARE_SYSNAND) ret += patchEmuNand(arm9Section, kernel9Size, process9Offset, process9Size, emuHeader, firm->section[2].address);
|
if(nandType != FIRMWARE_SYSNAND) ret += patchEmuNand(arm9Section, kernel9Size, process9Offset, process9Size, emuHeader, firm->section[2].address);
|
||||||
|
|
||||||
//Apply FIRM0/1 writes patches on SysNAND to protect A9LH
|
//Apply FIRM0/1 writes patches on SysNAND to protect A9LH
|
||||||
else if(isA9lhInstalled) ret += patchFirmWrites(process9Offset, process9Size);
|
else ret += patchFirmWrites(process9Offset, process9Size);
|
||||||
|
|
||||||
//Apply firmlaunch patches
|
//Apply firmlaunch patches
|
||||||
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
|
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
|
||||||
@ -185,7 +182,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
|
|||||||
if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size);
|
if(!ISDEVUNIT) ret += patchCheckForDevCommonKey(process9Offset, process9Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enableExceptionHandlers && isA9lhInstalled)
|
if(enableExceptionHandlers)
|
||||||
{
|
{
|
||||||
//ARM11 exception handlers
|
//ARM11 exception handlers
|
||||||
u32 codeSetOffset,
|
u32 codeSetOffset,
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode);
|
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode);
|
||||||
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lhInstalled, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers);
|
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers);
|
||||||
u32 patchTwlFirm(u32 firmVersion, bool doUnitinfoPatch);
|
u32 patchTwlFirm(u32 firmVersion, bool doUnitinfoPatch);
|
||||||
u32 patchAgbFirm(bool doUnitinfoPatch);
|
u32 patchAgbFirm(bool doUnitinfoPatch);
|
||||||
u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers);
|
u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers);
|
||||||
|
@ -39,8 +39,7 @@ extern FirmwareSource firmSource;
|
|||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
bool isA9lhInstalled,
|
bool isSafeMode = false,
|
||||||
isSafeMode = false,
|
|
||||||
isNoForceFlagSet = false;
|
isNoForceFlagSet = false;
|
||||||
u32 emuHeader;
|
u32 emuHeader;
|
||||||
FirmwareType firmType;
|
FirmwareType firmType;
|
||||||
@ -79,25 +78,20 @@ void main(void)
|
|||||||
|
|
||||||
nandType = (FirmwareSource)BOOTCFG_NAND;
|
nandType = (FirmwareSource)BOOTCFG_NAND;
|
||||||
firmSource = (FirmwareSource)BOOTCFG_FIRM;
|
firmSource = (FirmwareSource)BOOTCFG_FIRM;
|
||||||
isA9lhInstalled = BOOTCFG_A9LH != 0;
|
|
||||||
|
|
||||||
goto boot;
|
goto boot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ISA9LH)
|
detectAndProcessExceptionDumps();
|
||||||
{
|
installArm9Handlers();
|
||||||
detectAndProcessExceptionDumps();
|
|
||||||
installArm9Handlers();
|
|
||||||
}
|
|
||||||
|
|
||||||
firmType = NATIVE_FIRM;
|
firmType = NATIVE_FIRM;
|
||||||
isA9lhInstalled = ISA9LH;
|
|
||||||
|
|
||||||
//Get pressed buttons
|
//Get pressed buttons
|
||||||
u32 pressed = HID_PAD;
|
u32 pressed = HID_PAD;
|
||||||
|
|
||||||
//If it's a MCU reboot, try to force boot options
|
//If it's a MCU reboot, try to force boot options
|
||||||
if(ISA9LH && CFG_BOOTENV && needConfig != CREATE_CONFIGURATION)
|
if(CFG_BOOTENV && needConfig != CREATE_CONFIGURATION)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Always force a SysNAND boot when quitting AGB_FIRM
|
//Always force a SysNAND boot when quitting AGB_FIRM
|
||||||
@ -137,7 +131,7 @@ void main(void)
|
|||||||
pressed = HID_PAD;
|
pressed = HID_PAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ISA9LH && !CFG_BOOTENV && pressed == SAFE_MODE)
|
if(!CFG_BOOTENV && pressed == SAFE_MODE)
|
||||||
{
|
{
|
||||||
nandType = FIRMWARE_SYSNAND;
|
nandType = FIRMWARE_SYSNAND;
|
||||||
firmSource = FIRMWARE_SYSNAND;
|
firmSource = FIRMWARE_SYSNAND;
|
||||||
@ -174,21 +168,21 @@ void main(void)
|
|||||||
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
|
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
|
||||||
else if(pressed & BUTTON_R1)
|
else if(pressed & BUTTON_R1)
|
||||||
{
|
{
|
||||||
if(CONFIG(USESYSFIRM))
|
if(CONFIG(USEEMUFIRM))
|
||||||
{
|
|
||||||
nandType = FIRMWARE_EMUNAND;
|
|
||||||
firmSource = FIRMWARE_SYSNAND;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
nandType = FIRMWARE_SYSNAND;
|
nandType = FIRMWARE_SYSNAND;
|
||||||
firmSource = FIRMWARE_EMUNAND;
|
firmSource = FIRMWARE_EMUNAND;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nandType = FIRMWARE_EMUNAND;
|
||||||
|
firmSource = FIRMWARE_SYSNAND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Else, boot the NAND the user set to autoboot or the opposite one, depending on L,
|
/* Else, boot the NAND the user set to autoboot or the opposite one, depending on L,
|
||||||
with their own FIRM */
|
with their own FIRM */
|
||||||
else firmSource = nandType = (CONFIG(AUTOBOOTSYS) == ((pressed & BUTTON_L1) == BUTTON_L1)) ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
|
else firmSource = nandType = (CONFIG(AUTOBOOTEMU) == ((pressed & BUTTON_L1) == BUTTON_L1)) ? FIRMWARE_SYSNAND : FIRMWARE_EMUNAND;
|
||||||
|
|
||||||
//If we're booting EmuNAND or using EmuNAND FIRM, determine which one from the directional pad buttons, or otherwise from the config
|
//If we're booting EmuNAND or using EmuNAND FIRM, determine which one from the directional pad buttons, or otherwise from the config
|
||||||
if(nandType == FIRMWARE_EMUNAND || firmSource == FIRMWARE_EMUNAND)
|
if(nandType == FIRMWARE_EMUNAND || firmSource == FIRMWARE_EMUNAND)
|
||||||
@ -232,7 +226,7 @@ boot:
|
|||||||
|
|
||||||
if(!ISFIRMLAUNCH)
|
if(!ISFIRMLAUNCH)
|
||||||
{
|
{
|
||||||
configData.config = (configData.config & 0xFFFFFF00) | ((u32)isNoForceFlagSet << 7) | ((u32)ISA9LH << 6) | ((u32)firmSource << 3) | (u32)nandType;
|
configData.config = (configData.config & 0xFFFFFF80) | ((u32)isNoForceFlagSet << 6) | ((u32)firmSource << 3) | (u32)nandType;
|
||||||
writeConfig(false);
|
writeConfig(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +241,7 @@ boot:
|
|||||||
switch(firmType)
|
switch(firmType)
|
||||||
{
|
{
|
||||||
case NATIVE_FIRM:
|
case NATIVE_FIRM:
|
||||||
res = patchNativeFirm(firmVersion, nandType, emuHeader, isA9lhInstalled, isSafeMode, doUnitinfoPatch, enableExceptionHandlers);
|
res = patchNativeFirm(firmVersion, nandType, emuHeader, isSafeMode, doUnitinfoPatch, enableExceptionHandlers);
|
||||||
break;
|
break;
|
||||||
case TWL_FIRM:
|
case TWL_FIRM:
|
||||||
res = patchTwlFirm(firmVersion, doUnitinfoPatch);
|
res = patchTwlFirm(firmVersion, doUnitinfoPatch);
|
||||||
@ -258,7 +252,7 @@ boot:
|
|||||||
case SAFE_FIRM:
|
case SAFE_FIRM:
|
||||||
case SYSUPDATER_FIRM:
|
case SYSUPDATER_FIRM:
|
||||||
case NATIVE_FIRM1X2X:
|
case NATIVE_FIRM1X2X:
|
||||||
res = isA9lhInstalled ? patch1x2xNativeAndSafeFirm(enableExceptionHandlers) : 0;
|
res = patch1x2xNativeAndSafeFirm(enableExceptionHandlers);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +61,7 @@ typedef volatile s64 vs64;
|
|||||||
|
|
||||||
#define ISN3DS (PDN_MPCORE_CFG == 7)
|
#define ISN3DS (PDN_MPCORE_CFG == 7)
|
||||||
#define ISDEVUNIT (CFG_UNITINFO != 0)
|
#define ISDEVUNIT (CFG_UNITINFO != 0)
|
||||||
#define ISA9LH (!PDN_SPI_CNT)
|
#define ISSIGHAX (!(CFG_SYSPROT9 & 2))
|
||||||
#define ISSIGHAX (!PDN_SPI_CNT && !(CFG_SYSPROT9 & 2))
|
|
||||||
#define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0)
|
#define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0)
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
typedef struct __attribute__((packed))
|
||||||
|
Reference in New Issue
Block a user