summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMade <made111@gmx.de>2020-05-09 19:44:50 +0200
committerMade <made111@gmx.de>2020-05-09 19:44:50 +0200
commiteff30d81b4785428ca4e86383f665f9f03c76b9f (patch)
treea168324f6cb3f88716e1a630b58ac93e8a0b42c9
parent4abf7d45568d93040fdb86993e915ffdfc4c4a9e (diff)
parente1c517d34810fe83865e896a23e46a2ea089261f (diff)
Merge branch 'master' of https://github.com/martmists/pokediamond
-rw-r--r--INSTALL.md6
-rw-r--r--Makefile2
-rw-r--r--arm9/Makefile12
-rw-r--r--arm9/arm9.lcf137
-rw-r--r--arm9/arm9.lsf16
-rw-r--r--arm9/asm/crt0.s23
-rw-r--r--arm9/asm/libcard.s14
-rw-r--r--arm9/asm/libdgt.s4
-rw-r--r--arm9/asm/libfs.s3011
-rw-r--r--arm9/asm/libmwcc.s13
-rw-r--r--arm9/asm/unk_020023C0.s548
-rw-r--r--arm9/asm/unk_020061E8.s181
-rw-r--r--arm9/asm/unk_02006864.s2
-rw-r--r--arm9/asm/unk_020910EC.s55
-rw-r--r--arm9/data/rom2.s2
-rw-r--r--arm9/data/rom2_2.s4
-rw-r--r--arm9/data/rom2_3.s12
-rw-r--r--arm9/data/rom2_4.s9
-rw-r--r--arm9/global.inc20
-rw-r--r--arm9/lib/include/CARD_common.h6
-rw-r--r--arm9/lib/include/CARD_pullOut.h6
-rw-r--r--arm9/lib/include/CARD_rom.h39
-rw-r--r--arm9/lib/include/DGT_common.h6
-rw-r--r--arm9/lib/include/DGT_dgt.h6
-rw-r--r--arm9/lib/include/FS_archive.h212
-rw-r--r--arm9/lib/include/FS_command.h11
-rw-r--r--arm9/lib/include/FS_file.h222
-rw-r--r--arm9/lib/include/FS_mw_dtor.h16
-rw-r--r--arm9/lib/include/FS_overlay.h55
-rw-r--r--arm9/lib/include/FS_rom.h14
-rw-r--r--arm9/lib/include/FSi_util.h46
-rw-r--r--arm9/lib/include/MI_byteAccess.h14
-rw-r--r--arm9/lib/include/MI_dma.h6
-rw-r--r--arm9/lib/include/MI_exMemory.h9
-rw-r--r--arm9/lib/include/MI_memory.h10
-rw-r--r--arm9/lib/include/MI_uncompress.h6
-rw-r--r--arm9/lib/include/OS_cache.h9
-rw-r--r--arm9/lib/include/OS_printf.h8
-rw-r--r--arm9/lib/include/OS_spinLock.h2
-rw-r--r--arm9/lib/include/OS_system.h2
-rw-r--r--arm9/lib/include/OS_thread.h3
-rw-r--r--arm9/lib/include/mmap.h2
-rw-r--r--arm9/lib/src/FS_archive.c445
-rw-r--r--arm9/lib/src/FS_command.c75
-rw-r--r--arm9/lib/src/FS_command_default.c468
-rw-r--r--arm9/lib/src/FS_file.c242
-rw-r--r--arm9/lib/src/FS_overlay.c320
-rw-r--r--arm9/lib/src/FS_rom.c118
-rw-r--r--arm9/lib/src/OS_reset.c1
-rw-r--r--arm9/modules/13/asm/module_13_arm2.s8
-rw-r--r--arm9/src/poke_overlay.c203
-rw-r--r--arm9/src/string_util.c11
-rw-r--r--arm9/undefined_syms.txt4
-rw-r--r--global.inc2
-rw-r--r--tools/scaninc/.gitignore1
-rw-r--r--tools/scaninc/LICENSE19
-rw-r--r--tools/scaninc/Makefile18
-rw-r--r--tools/scaninc/asm_file.cpp192
-rw-r--r--tools/scaninc/asm_file.h119
-rw-r--r--tools/scaninc/c_file.cpp307
-rw-r--r--tools/scaninc/c_file.h57
-rw-r--r--tools/scaninc/scaninc.cpp121
-rw-r--r--tools/scaninc/scaninc.h59
-rw-r--r--tools/scaninc/source_file.cpp125
-rw-r--r--tools/scaninc/source_file.h71
-rw-r--r--undefined_syms.txt2
66 files changed, 4085 insertions, 3684 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 2d42c2b8..ca080afb 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -20,15 +20,13 @@ Building the ROM requires the following packages:
* make
* git
-* build-essentials
+* build-essentials (build-essential on Ubuntu)
* binutils-arm-none-eabi
* wine (to run the mwcc executables)
-* libpng-devel
+* libpng-devel (libpng-dev on Ubuntu)
NOTE: If you are using Arch/Manjaro or Void you will only need base-devel instead of build-essentials or make or git. You will still need wine.
-Also, if you are using WSL on Windows, please pass NOWINE=1 when compiling, and wine is not necessary for a WSL environment.
-
#### Windows
Before following the respective guides, please install devkitARM and ensure the DEVKITPRO and DEVKITARM variables are added to bashrc such that:
diff --git a/Makefile b/Makefile
index 3a4c2e29..fe2a04ba 100644
--- a/Makefile
+++ b/Makefile
@@ -258,7 +258,7 @@ arm7:
$(MAKE) -C arm7
$(BINFILES): %.bin: %.sbin
- cp $< $@
+ @cp $< $@
$(ELF): $(O_FILES) $(BUILD_DIR)/$(LD_SCRIPT) $(BINFILES)
# Hack because mwldarm doesn't like the sbin suffix
diff --git a/arm9/Makefile b/arm9/Makefile
index 9d03e875..bc8c8491 100644
--- a/arm9/Makefile
+++ b/arm9/Makefile
@@ -91,15 +91,16 @@ OBJCOPY := $(CROSS)objcopy
# ./tools/mwccarm/2.0/base/mwasmarm.exe -proc arm5te asm/arm9_thumb.s -o arm9.o
ASFLAGS = -proc arm5te -i ..
-CFLAGS = -O4,p -proc arm946e -fp soft -lang c99 -Cpp_exceptions off -ir ../include -ir ../include-mw -ir lib/include -interworking
+CFLAGS = -O4,p -proc arm946e -fp soft -lang c99 -Cpp_exceptions off -ir ../include -ir ../include-mw -ir lib/include -interworking -DFS_IMPLEMENT -enum int
LDFLAGS = -map -nodead -w off -proc v5te -interworking -map -symtab -m _start
####################### Other Tools #########################
# DS TOOLS
-SHA1SUM = sha1sum
-JSONPROC = $(TOOLS_DIR)/jsonproc/jsonproc
-GFX = $(TOOLS_DIR)/nitrogfx/nitrogfx
+SHA1SUM = sha1sum --quiet
+JSONPROC = $(TOOLS_DIR)/jsonproc/jsonproc$(EXE)
+GFX = $(TOOLS_DIR)/nitrogfx/nitrogfx$(EXE)
+SCANINC = $(TOOLS_DIR)/scaninc/scaninc$(EXE)
MWASMARM_PATCHER = $(TOOLS_DIR)/mwasmarm_patcher/mwasmarm_patcher$(EXE) -q
TOOLDIRS = $(filter-out $(TOOLS_DIR)/mwccarm $(TOOLS_DIR)/bin,$(wildcard $(TOOLS_DIR)/*))
@@ -124,6 +125,7 @@ MAKEFLAGS += --no-print-directory
all: $(ROM)
@$(SHA1SUM) -c $(TARGET).sha1
+ @echo $(ROM): OK
clean: mostlyclean
make -C $(TOOLS_DIR)/mwasmarm_patcher clean
@@ -155,7 +157,7 @@ build/src/FUN_020910A4.o: MWCCVERSION = 1.2/sp2p3
####################### Everything Else ######################
ifeq (,$(NODEP))
-$(BUILD_DIR)/%.o: dep = $(shell grep -E '(#\s*|\.)(include|incbin)\s*"(\S+?)"' $*.[cs] | cut -d'"' -f2 | sort -u)
+$(BUILD_DIR)/%.o: dep = $(shell $(SCANINC) -I ../include -I ../include-mw -I lib/include $*.[cs])
else
$(BUILD_DIR)/%.o: dep :=
endif
diff --git a/arm9/arm9.lcf b/arm9/arm9.lcf
index d5ebf272..91b80e07 100644
--- a/arm9/arm9.lcf
+++ b/arm9/arm9.lcf
@@ -112,15 +112,20 @@ MEMORY {
SECTIONS {
#include "undefined_syms.txt"
.arm9 : {
+ ALIGNALL(4); . = ALIGN(32);
SDK_STATIC_START = .;
+ SDK_STATIC_TEXT_START = .;
secure.o (.text)
crt0.o (.text)
- crt0.o (.version)
+ crt0.o (.rodata)
+ * (.version)
main.o (.text)
FUN_02000DF4.o (.text)
unk_02000E0C.o (.text)
string_util.o (.text)
unk_020023C0.o (.text)
+ poke_overlay.o (.text)
+ unk_020061E8.o (.text)
filesystem.o (.text)
unk_02006864.o (.text)
script.o (.text)
@@ -201,7 +206,12 @@ SECTIONS {
SND_bank.o (.text)
PXI_init.o (.text)
PXI_fifo.o (.text)
- libfs.o (.text)
+ FS_command.o (.text)
+ FS_command_default.o (.text)
+ FS_archive.o (.text)
+ FS_file.o (.text)
+ FS_rom.o (.text)
+ FS_overlay.o (.text)
libdgt.o (.text)
libcp.o (.text)
libspi.o (.text)
@@ -216,56 +226,93 @@ SECTIONS {
libc.o (.text)
/* MWCC library */
libmwcc.o (.text)
- rom2.o (.data)
- string_util.o (.data)
- rom2_2.o (.data)
+
+ /* Text data */
+ rom2.o (.rodata)
+ string_util.o (.rodata)
+ rom2_2.o (.rodata)
+ FS_command.o (.rodata)
+ FS_command_default.o (.rodata)
+ FS_archive.o (.rodata)
+ FS_file.o (.rodata)
+ FS_rom.o (.rodata)
+ FS_overlay.o (.rodata)
+ rom2_3.o (.rodata)
+ libmwcc.o (.rodata)
+ . = ALIGN(32);
+ SDK_STATIC_TEXT_END = .;
+
+ SDK_STATIC_DATA_START = .;
+ rom2_3.o (.data)
+ FS_command.o (.data)
+ FS_command_default.o (.data)
+ FS_archive.o (.data)
+ FS_file.o (.data)
+ FS_rom.o (.data)
+ FS_overlay.o (.data)
+ rom2_4.o (.data)
+ SDK_STATIC_DATA_END = .;
SDK_STATIC_END = .;
SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START;
} > arm9
.arm9.bss :
{
+ /* ALIGNALL(4); . = ALIGN(32); */
SDK_STATIC_BSS_START = .;
- /* 0x02106FA0 */ gBacklightTop = SDK_STATIC_BSS_START;
- /* 0x02106FA0 */ gBacklightTop_2 = gBacklightTop + 0x0;
- /* 0x021C48B8 */ gUnknown21C48B8 = gBacklightTop_2 + 0xBD918;
- /* 0x021C4918 */ gUnk021C4918 = gUnknown21C48B8 + 0x60;
- /* 0x021C8C70 */ gUnk021C8C70 = gUnk021C4918 + 0x4358;
- /* 0x021D341C */ OSi_IrqCallbackInfo = gUnk021C8C70 + 0xA7AC;
- /* 0x021D347C */ isInitialized = OSi_IrqCallbackInfo + 0x60;
- /* 0x021D3480 */ OSi_StackForDestructor = isInitialized + 0x4;
- /* 0x021D3484 */ OSi_RescheduleCount = OSi_StackForDestructor + 0x4;
- /* 0x021D3488 */ OSi_ThreadIdCount = OSi_RescheduleCount + 0x4;
- /* 0x021D348C */ OSi_SystemCallbackInSwitchThread = OSi_ThreadIdCount + 0x4;
- /* 0x021D3490 */ OSi_CurrentThreadPtr = OSi_SystemCallbackInSwitchThread + 0x4;
- /* 0x021D3494 */ OSi_IsThreadInitialized = OSi_CurrentThreadPtr + 0x4;
- /* 0x021D3498 */ OSi_ThreadInfo = OSi_IsThreadInitialized + 0x4;
- /* 0x021D34A8 */ OSi_IdleThread = OSi_ThreadInfo + 0x10;
- /* 0x021D3568 */ OSi_LauncherThread = OSi_IdleThread + 0xC0;
- /* 0x021D3628 */ OSi_IdleThreadStack = OSi_LauncherThread + 0xC0;
- /* 0x021D36F0 */ OSi_Initialized = OSi_IdleThreadStack + 0xC8;
- /* 0x021D36F4 */ OSi_MainExArenaEnabled = OSi_Initialized + 0x4;
- /* 0x021D36F8 */ OSiHeapInfo = OSi_MainExArenaEnabled + 0x4;
- /* 0x021D371C */ OSi_UserExceptionHandler = OSiHeapInfo + 0x24;
- /* 0x021D3720 */ OSi_UserExceptionHandlerArg = OSi_UserExceptionHandler + 0x4;
- /* 0x021D3724 */ OSi_DebuggerHandler = OSi_UserExceptionHandlerArg + 0x4;
- /* 0x021D3728 */ OSi_ExContext = OSi_DebuggerHandler + 0x4;
- /* 0x021D37A8 */ OSi_TimerReserved = OSi_ExContext + 0x80;
- /* 0x021D37AC */ OSi_UseTick = OSi_TimerReserved + 0x4;
- /* 0x021D37B0 */ OSi_NeedResetTimer = OSi_UseTick + 0x4;
- /* 0x021D37B4 */ OSi_TickCounter = OSi_NeedResetTimer + 0x4;
- /* 0x021D37BC */ OSi_UseAlarm = OSi_TickCounter + 0x8;
- /* 0x021D37C0 */ OSi_AlarmQueue = OSi_UseAlarm + 0x4;
- /* 0x021D37C8 */ OSi_UseVAlarm = OSi_AlarmQueue + 0x8;
- /* 0x021D37CC */ OSi_PreviousVCount = OSi_UseVAlarm + 0x4;
- /* 0x021D37D0 */ OSi_VFrameCount = OSi_PreviousVCount + 0x4;
- /* 0x021D37D4 */ OSi_VAlarmQueue = OSi_VFrameCount + 0x4;
- /* 0x021D37DC */ OSi_IsInitReset = OSi_VAlarmQueue + 0x8;
- /* 0x021D37E0 */ OSi_IsResetOccurred = OSi_IsInitReset + 0x4;
- /* 0x021D37E4 */ OSi_vramExclusive = OSi_IsResetOccurred + 0x4;
- /* 0x021D37E8 */ OSi_vramLockId = OSi_vramExclusive + 0x4;
- /* 0x021D55C0 */ cardi_common = OSi_vramLockId + 0x1DD8;
- /* 0x021D74E0 */ SDK_STATIC_BSS_END = cardi_common + 0x1F20;
+ /* .sbss */
+ gBacklightTop = 0x02106FA0;
+ gBacklightTop_2 = 0x02106FA0;
+ /* .bss */
+ gLoadedOverlays = 0x021C45B0;
+ gUnknown21C48B8 = 0x021C48B8;
+ gUnk021C4918 = 0x021C4918;
+ gUnk021C8C70 = 0x021C8C70;
+ OSi_IrqCallbackInfo = 0x021D341C;
+ isInitialized = 0x021D347C;
+ OSi_StackForDestructor = 0x021D3480;
+ OSi_RescheduleCount = 0x021D3484;
+ OSi_ThreadIdCount = 0x021D3488;
+ OSi_SystemCallbackInSwitchThread = 0x021D348C;
+ OSi_CurrentThreadPtr = 0x021D3490;
+ OSi_IsThreadInitialized = 0x021D3494;
+ OSi_ThreadInfo = 0x021D3498;
+ OSi_IdleThread = 0x021D34A8;
+ OSi_LauncherThread = 0x021D3568;
+ OSi_IdleThreadStack = 0x021D3628;
+ OSi_Initialized = 0x021D36F0;
+ OSi_MainExArenaEnabled = 0x021D36F4;
+ OSiHeapInfo = 0x021D36F8;
+ OSi_UserExceptionHandler = 0x021D371C;
+ OSi_UserExceptionHandlerArg = 0x021D3720;
+ OSi_DebuggerHandler = 0x021D3724;
+ OSi_ExContext = 0x021D3728;
+ OSi_TimerReserved = 0x021D37A8;
+ OSi_UseTick = 0x021D37AC;
+ OSi_NeedResetTimer = 0x021D37B0;
+ OSi_TickCounter = 0x021D37B4;
+ OSi_UseAlarm = 0x021D37BC;
+ OSi_AlarmQueue = 0x021D37C0;
+ OSi_UseVAlarm = 0x021D37C8;
+ OSi_PreviousVCount = 0x021D37CC;
+ OSi_VFrameCount = 0x021D37D0;
+ OSi_VAlarmQueue = 0x021D37D4;
+ OSi_IsInitReset = 0x021D37DC;
+ OSi_IsResetOccurred = 0x021D37E0;
+ OSi_vramExclusive = 0x021D37E4;
+ OSi_vramLockId = 0x021D37E8;
+ cardi_common = 0x021D55C0;
+ arc_list = 0x021D53E8;
+ current_dir_pos = 0x021D53EC;
+ is_init = 0x021D53F8;
+ fsi_card_lock_id = 0x021D53FC;
+ fsi_default_dma_no = 0x021D5400;
+ fsi_ovt9 = 0x021D5404;
+ fsi_ovt7 = 0x021D540C;
+ fsi_arc_rom = 0x021D5414;
+ __global_destructor_chain = 0x021D74C8;
+ /* . = ALIGN(32); */
+ SDK_STATIC_BSS_END = 0x021D74E0;
SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START;
} >> arm9
diff --git a/arm9/arm9.lsf b/arm9/arm9.lsf
index 16cbdc72..a0f6e04f 100644
--- a/arm9/arm9.lsf
+++ b/arm9/arm9.lsf
@@ -5,6 +5,7 @@ Static arm9
Object main.o
Object FUN_02000DF4.o
Object unk_02000E0C.o
+ Object rom2.o
Object string_util.o
Object unk_020023C0.o
Object filesystem.o
@@ -84,7 +85,13 @@ Static arm9
Object SND_bank.o
Object PXI_init.o
Object PXI_fifo.o
- Object libfs.o
+ Object rom2_2.o
+ Object FS_command.o
+ Object FS_command_default.o
+ Object FS_archive.o
+ Object FS_file.o
+ Object FS_rom.o
+ Object FS_overlay.o
Object libdgt.o
Object libcp.o
Object libspi.o
@@ -96,10 +103,9 @@ Static arm9
Object libmath.o
Object libstd.o
Object libc.o
+ Object rom2_3.o
Object libmwcc.o
- Object rom2.o
- Object string_util.o
- Object rom2_2.o
+ Object rom2_4.o
}
Autoload ITCM
@@ -286,7 +292,7 @@ Overlay MODULE_31
Overlay MODULE_32
{
Address 0x02254840
- Object FILE_28D800.o
+ Object module_32.o
}
Overlay MODULE_33
{
diff --git a/arm9/asm/crt0.s b/arm9/asm/crt0.s
index aaf2d22f..05a91b28 100644
--- a/arm9/asm/crt0.s
+++ b/arm9/asm/crt0.s
@@ -255,32 +255,43 @@ OSi_ReferSymbol: ; 0x02000B60
NitroStartUp: ; 0x02000B64
bx lr
+ .section .rodata
.global _start_ModuleParams
-_start_ModuleParams:
+_start_ModuleParams: ; 0x02000B68
.word SDK_AUTOLOAD_LIST
.word SDK_AUTOLOAD_LIST_END
.word SDK_AUTOLOAD_START
.word SDK_STATIC_BSS_START
.word SDK_STATIC_BSS_END
-
- .balign 16, 0
-
- .section .version
+ .word 0 ; Compressed static init end
; NITRO SDK 3.2.30001
.word (3 << 24) | (2 << 16) | 30001
.word 0xdec00621 ; Nitro code BE
.word 0x2106c0de ; Nitro code LE
-
+
# strings
+ # .section .version
.balign 4
+ .global _SDK_NintendoDWC
+_SDK_NintendoDWC: ; 0x02000b8c
.asciz "[SDK+NINTENDO:DWC1.2.30006.061019.2254_DWC_1_2_PLUS6]"
.balign 4
+ .global _SDK_NintendoWiFi
+_SDK_NintendoWiFi: ; 0x02000bc4
.asciz "[SDK+NINTENDO:WiFi1.2.30000.0609050341]"
.balign 4
+ .global _SDK_UbiquitousCPS
+_SDK_UbiquitousCPS: ; 0x02000bec
.asciz "[SDK+UBIQUITOUS:CPS]"
.balign 4
+ .global _SDK_UbiquitousSSL
+_SDK_UbiquitousSSL: ; 0x02000c04
.asciz "[SDK+UBIQUITOUS:SSL]"
.balign 4
+ .global _SDK_AbiossolibVCT
+_SDK_AbiossolibVCT: ; 0x02000c1c
.asciz "[SDK+Abiosso:libVCT 1.0.1_ec]"
.balign 4
+ .global _SDK_NintendoBackup
+_SDK_NintendoBackup: ; 0x02000c3c
.asciz "[SDK+NINTENDO:BACKUP]"
diff --git a/arm9/asm/libcard.s b/arm9/asm/libcard.s
index 664e85f5..959c6f64 100644
--- a/arm9/asm/libcard.s
+++ b/arm9/asm/libcard.s
@@ -558,12 +558,14 @@ CARD_WaitBackupAsync: ; 0x020D6DB8
.balign 4
_020D6DC0: .word CARDi_WaitAsync
+ .extern _SDK_NintendoBackup
+
arm_func_start CARD_IdentifyBackup
CARD_IdentifyBackup: ; 0x020D6DC4
stmdb sp!, {r4-r7,lr}
sub sp, sp, #0x4
mov r5, r0
- ldr r0, _020D6F00 ; =0x02000C3C
+ ldr r0, _020D6F00 ; =_SDK_NintendoBackup
ldr r7, _020D6F04 ; =0x021D55C0
bl OSi_ReferSymbol
_020D6DDC: ; 0x020D6DDC
@@ -648,7 +650,7 @@ _020D6EE0:
ldmia sp!, {r4-r7,lr}
bx lr
.balign 4
-_020D6F00: .word 0x02000C3C
+_020D6F00: .word _SDK_NintendoBackup
_020D6F04: .word 0x021D55C0
_020D6F08: .word 0x021D3498
@@ -666,7 +668,7 @@ CARDi_RequestStreamCommand: ; 0x020D6F20
stmdb sp!, {r4-r10,lr}
mov r10, r0
ldr r6, _020D7004 ; =0x021D55C0
- ldr r0, _020D7008 ; =0x02000C3C
+ ldr r0, _020D7008 ; =_SDK_NintendoBackup
mov r9, r1
mov r8, r2
mov r7, r3
@@ -726,7 +728,7 @@ _020D6FE8: ; 0x020D6FE8
bx lr
.balign 4
_020D7004: .word 0x021D55C0
-_020D7008: .word 0x02000C3C
+_020D7008: .word _SDK_NintendoBackup
_020D700C: .word CARDi_RequestStreamCommandCore
_020D7010: .word 0x021D3498
@@ -736,7 +738,7 @@ CARDi_RequestStreamCommandCore:
sub sp, sp, #0x4
mov r9, r0
ldr r8, [r9, #0x2c]
- ldr r0, _020D720C ; =0x02000C3C
+ ldr r0, _020D720C ; =_SDK_NintendoBackup
ldr r7, [r9, #0x34]
ldr r10, [r9, #0x30]
mov r6, #0x100
@@ -878,7 +880,7 @@ _020D71E8: ; 0x020D71E8
ldmia sp!, {r4-r11,lr}
bx lr
.balign 4
-_020D720C: .word 0x02000C3C
+_020D720C: .word _SDK_NintendoBackup
arm_func_start CARDi_GetRomAccessor
CARDi_GetRomAccessor: ; 0x020D7210
diff --git a/arm9/asm/libdgt.s b/arm9/asm/libdgt.s
index d5ef358d..02a3293f 100644
--- a/arm9/asm/libdgt.s
+++ b/arm9/asm/libdgt.s
@@ -403,8 +403,8 @@ _020D2D6C: .word 0xEFCDAB89
_020D2D70: .word 0x98BADCFE
_020D2D74: .word 0x10325476
- arm_func_start MATH_CalcHMACSHA1
-MATH_CalcHMACSHA1: ; 0x020D2D78
+ arm_func_start DGT_Hash2CalcHmac
+DGT_Hash2CalcHmac: ; 0x020D2D78
stmdb sp!, {r4-r8,lr}
sub sp, sp, #0xa0
ldr lr, _020D2E00 ; =0x02106A04
diff --git a/arm9/asm/libfs.s b/arm9/asm/libfs.s
deleted file mode 100644
index d9b791b8..00000000
--- a/arm9/asm/libfs.s
+++ /dev/null
@@ -1,3011 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
- .section .text
-
- arm_func_start FSi_TranslateCommand
-FSi_TranslateCommand:
- stmdb sp!, {r4-r8,lr}
- mov r8, r0
- ldr r0, [r8, #0xc]
- mov r7, r1
- mov r1, #0x1
- ldr r5, [r8, #0x8]
- mov r4, r1, lsl r7
- ands r0, r0, #0x4
- moveq r1, #0x0
- cmp r1, #0x0
- ldrne r0, [r5, #0x1c]
- orrne r0, r0, #0x200
- strne r0, [r5, #0x1c]
- ldreq r0, [r5, #0x1c]
- orreq r0, r0, #0x100
- streq r0, [r5, #0x1c]
- ldr r0, [r5, #0x58]
- ands r0, r0, r4
- beq _020CFFE4
- ldr r2, [r5, #0x54]
- mov r0, r8
- mov r1, r7
- blx r2
- mov r6, r0
- cmp r6, #0x8
- addls pc, pc, r6, lsl #0x2
- b _020CFFE8
-_020CFFA0:
- b _020CFFC4
- b _020CFFC4
- b _020CFFE8
- b _020CFFE8
- b _020CFFC4
- b _020CFFE8
- b _020CFFE8
- b _020CFFE8
- b _020CFFCC
-_020CFFC4:
- str r6, [r8, #0x14]
- b _020CFFE8
-_020CFFCC:
- ldr r1, [r5, #0x58]
- mvn r0, r4
- and r0, r1, r0
- str r0, [r5, #0x58]
- mov r6, #0x7
- b _020CFFE8
-_020CFFE4:
- mov r6, #0x7
-_020CFFE8:
- cmp r6, #0x7
- bne _020D0004
- ldr r1, _020D00AC ; =0x02103F80
- mov r0, r8
- ldr r1, [r1, r7, lsl #0x2]
- blx r1
- mov r6, r0
-_020D0004:
- cmp r6, #0x6
- bne _020D0060
- ldr r0, [r8, #0xc]
- ands r0, r0, #0x4
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- beq _020D00A0
- bl OS_DisableInterrupts
- ldr r1, [r5, #0x1c]
- mov r4, r0
- ands r0, r1, #0x200
- beq _020D0050
- add r6, r5, #0xc
-_020D003C:
- mov r0, r6
- bl OS_SleepThread
- ldr r0, [r5, #0x1c]
- ands r0, r0, #0x200
- bne _020D003C
-_020D0050:
- mov r0, r4
- ldr r6, [r8, #0x14]
- bl OS_RestoreInterrupts
- b _020D00A0
-_020D0060:
- ldr r0, [r8, #0xc]
- ands r0, r0, #0x4
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- ldrne r0, [r5, #0x1c]
- bicne r0, r0, #0x200
- strne r0, [r5, #0x1c]
- strne r6, [r8, #0x14]
- bne _020D00A0
- ldr r1, [r5, #0x1c]
- mov r0, r8
- bic r2, r1, #0x100
- mov r1, r6
- str r2, [r5, #0x1c]
- bl FSi_ReleaseCommand
-_020D00A0:
- mov r0, r6
- ldmia sp!, {r4-r8,lr}
- bx lr
- .balign 4
-_020D00AC: .word 0x02103F80
-
- arm_func_start FSi_ReleaseCommand
-FSi_ReleaseCommand:
- stmdb sp!, {r4-r6,lr}
- mov r6, r0
- mov r5, r1
- bl OS_DisableInterrupts
- ldr r1, [r6, #0x0]
- mov r4, r0
- ldr r0, [r6, #0x4]
- cmp r1, #0x0
- strne r0, [r1, #0x4]
- cmp r0, #0x0
- strne r1, [r0, #0x0]
- mov r0, #0x0
- str r0, [r6, #0x0]
- ldr r1, [r6, #0x0]
- add r0, r6, #0x18
- str r1, [r6, #0x4]
- ldr r1, [r6, #0xc]
- bic r1, r1, #0x4f
- str r1, [r6, #0xc]
- str r5, [r6, #0x14]
- bl OS_WakeupThread
- mov r0, r4
- bl OS_RestoreInterrupts
- ldmia sp!, {r4-r6,lr}
- bx lr
-
- arm_func_start FSi_CloseFileCommand
-FSi_CloseFileCommand: ; 0x020D0114
- mov r0, #0x0
- bx lr
-
- arm_func_start FSi_OpenFileDirectCommand
-FSi_OpenFileDirectCommand: ; 0x020D011C
- ldr r1, [r0, #0x30]
- str r1, [r0, #0x24]
- ldr r1, [r0, #0x30]
- str r1, [r0, #0x2c]
- ldr r1, [r0, #0x34]
- str r1, [r0, #0x28]
- ldr r1, [r0, #0x38]
- str r1, [r0, #0x20]
- mov r0, #0x0
- bx lr
-
- arm_func_start FSi_OpenFileFastCommand
-FSi_OpenFileFastCommand: ; 0x020D0144
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x14
- mov r5, r0
- ldr r1, [r5, #0x8]
- ldr r4, [r5, #0x34]
- ldr r0, [r1, #0x30]
- mov r2, r4, lsl #0x3
- cmp r2, r0
- addcs sp, sp, #0x14
- movcs r0, #0x1
- ldmcsia sp!, {r4-r5,lr}
- bxcs lr
- str r1, [sp, #0x8]
- ldr r1, [r1, #0x2c]
- add r0, sp, #0x8
- add r3, r1, r2
- add r1, sp, #0x0
- mov r2, #0x8
- str r3, [sp, #0xc]
- bl FSi_ReadTable
-_020D0194:
- cmp r0, #0
- addne sp, sp, #0x14
- ldmneia sp!, {r4-r5,lr}
- bxne lr
- ldr r1, [sp]
- mov r0, r5
- str r1, [r5, #0x30]
- ldr r2, [sp, #0x4]
- mov r1, #7
- str r2, [r5, #0x34]
- str r4, [r5, #0x38]
- bl FSi_TranslateCommand
- add sp, sp, #0x14
- ldmia sp!, {r4-r5,lr}
- bx lr
-
- arm_func_start FSi_GetPathCommand
-FSi_GetPathCommand: ; 0x020D01D0
- stmdb sp!, {r4-r11,lr}
- sub sp, sp, #0xe4
- mov r4, r0
- ldr r1, [r4, #0x8]
- add r0, sp, #0x98
- add r11, r4, #0x30
- str r1, [sp, #0x0]
- bl FS_InitFile
- ldr r0, [r4, #0x8]
- str r0, [sp, #0xa0]
- ldr r0, [r4, #0xc]
- ands r0, r0, #0x20
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- ldrneh r5, [r4, #0x24]
- movne r4, #0x10000
- bne _020D02BC
- ldrh r0, [r11, #0x8]
- ldr r4, [r4, #0x20]
- cmp r0, #0x0
- ldrneh r5, [r11, #0xa]
- bne _020D02BC
- mov r10, #0x0
- mov r9, r10
- mov r5, #0x10000
- add r8, sp, #0x98
- mov r6, #0x3
- mov r7, #0x1
-_020D0244:
- mov r0, r8
- mov r1, r10
- bl FSi_SeekDirDirect
- add r2, sp, #0x4
- cmp r10, #0x0
- mov r0, r8
- mov r1, r6
- ldreq r9, [sp, #0xc4]
- str r2, [sp, #0xc8]
- str r7, [sp, #0xcc]
- bl FSi_TranslateCommand
-_020D0270:
- cmp r0, #0x0
- bne _020D02A8
-_020D0278:
- ldr r0, [sp, #0x10]
- cmp r0, #0x0
- bne _020D0294
- ldr r0, [sp, #0x8]
- cmp r0, r4
- ldreqh r5, [sp, #0xbc]
- beq _020D02A8
-_020D0294:
- mov r0, r8
- mov r1, r6
- bl FSi_TranslateCommand
- cmp r0, #0x0
- beq _020D0278
-_020D02A8:
- cmp r5, #0x10000
- bne _020D02BC
- add sl, sl, #0x1
- cmp sl, r9
- bcc _020D0244
-_020D02BC:
- cmp r5, #0x10000
- moveq r0, #0x0
- streqh r0, [r11, #0x8]
- addeq sp, sp, #0xe4
- moveq r0, #0x1
- ldmeqia sp!, {r4-r11,lr}
- bxeq lr
- ldrh r0, [r11, #0x8]
- cmp r0, #0x0
- bne _020D03B8
- ldr r0, [sp, #0x0]
- mov r1, #0x0
- ldr r0, [r0, #0x0]
- cmp r0, #0xff
- addls r9, r1, #0x1
- bls _020D0308
- cmp r0, #0xff00
- addls r9, r1, #0x2
- addhi r9, r1, #0x3
-_020D0308:
- cmp r4, #0x10000
- ldrne r0, [sp, #0x14]
- add r9, r9, #0x2
- addne r9, r9, r0
- mov r10, r5
- cmp r5, #0x0
- beq _020D03AC
- add r0, sp, #0x98
- mov r1, r5
- bl FSi_SeekDirDirect
- add r8, sp, #0x98
- mov r6, #0x3
- mov r7, #0x1
-_020D033C:
- ldr r1, [sp, #0xc4]
- mov r0, r8
- bl FSi_SeekDirDirect
- add r2, sp, #0x4
- mov r0, r8
- mov r1, r6
- str r2, [sp, #0xc8]
- str r7, [sp, #0xcc]
- bl FSi_TranslateCommand
-_020D0360:
- cmp r0, #0x0
- bne _020D03A0
-_020D0368:
- ldr r0, [sp, #0x10]
- cmp r0, #0x0
- beq _020D038C
- ldrh r0, [sp, #0x8]
- cmp r0, sl
- ldreq r0, [sp, #0x14]
- addeq r0, r0, #0x1
- addeq r9, r9, r0
- beq _020D03A0
-_020D038C:
- mov r0, r8
- mov r1, r6
- bl FSi_TranslateCommand
- cmp r0, #0x0
- beq _020D0368
-_020D03A0:
- ldrh sl, [sp, #0xbc]
- cmp sl, #0x0
- bne _020D033C
-_020D03AC:
- add r0, r9, #0x1
- strh r0, [r11, #0x8]
- strh r5, [r11, #0xa]
-_020D03B8:
- ldr r7, [r11, #0x0]
- cmp r7, #0x0
- addeq sp, sp, #0xe4
- moveq r0, #0x0
- ldmeqia sp!, {r4-r11,lr}
- bxeq lr
- ldrh r6, [r11, #0x8]
- ldr r0, [r11, #0x4]
- cmp r0, r6
- addcc sp, sp, #0xe4
- movcc r0, #0x1
- ldmccia sp!, {r4-r11,lr}
- bxcc lr
- ldr r0, [sp, #0x0]
- mov r9, #0x0
- ldr r0, [r0, #0x0]
- cmp r0, #0xff
- movls r8, #0x1
- bls _020D0410
- cmp r0, #0xff00
- movls r8, #0x2
- movhi r8, #0x3
-_020D0410:
- ldr r0, [sp, #0x0]
- mov r1, r7
- mov r2, r8
- bl MI_CpuCopy8
- add r1, r9, r8
- ldr r0, _020D058C ; =0x0210682C
- add r1, r7, r1
- mov r2, #0x2
- bl MI_CpuCopy8
- add r0, sp, #0x98
- mov r1, r5
- bl FSi_SeekDirDirect
- cmp r4, #0x10000
- beq _020D04C4
- add r3, sp, #0x4
- mov r2, #0x0
- add r0, sp, #0x98
- mov r1, #0x3
- str r3, [sp, #0xc8]
- str r2, [sp, #0xcc]
- bl FSi_TranslateCommand
-_020D0464:
- cmp r0, #0x0
- bne _020D04A0
- add r9, sp, #0x98
- mov r8, #0x3
-_020D0474:
- ldr r0, [sp, #0x10]
- cmp r0, #0x0
- bne _020D048C
- ldr r0, [sp, #0x8]
- cmp r0, r4
- beq _020D04A0
-_020D048C:
- mov r0, r9
- mov r1, r8
- bl FSi_TranslateCommand
- cmp r0, #0x0
- beq _020D0474
-_020D04A0:
- ldr r0, [sp, #0x14]
- add r1, r7, r6
- add r4, r0, #0x1
- add r0, sp, #0x18
- mov r2, r4
- sub r1, r1, r4
- bl MI_CpuCopy8
- sub r6, r6, r4
- b _020D04D4
-_020D04C4:
- add r0, r7, r6
- mov r1, #0x0
- strb r1, [r0, #-0x1]
- sub r6, r6, #0x1
-_020D04D4:
- cmp r5, #0x0
- beq _020D057C
- add r10, sp, #0x98
- add r11, sp, #0x4
- mov r4, #0x3
- mov r9, #0x0
- mov r8, #0x2f
-_020D04F0:
- ldr r1, [sp, #0xc4]
- mov r0, r10
- bl FSi_SeekDirDirect
- add r2, r7, r6
- mov r0, r10
- mov r1, r4
- str r11, [sp, #0xc8]
- str r9, [sp, #0xcc]
- strb r8, [r2, #-0x1]
- sub r6, r6, #0x1
- bl FSi_TranslateCommand
-_020D051C:
- cmp r0, #0x0
- bne _020D0570
-_020D0524:
- ldr r0, [sp, #0x10]
- cmp r0, #0x0
- beq _020D055C
- ldrh r0, [sp, #0x8]
- cmp r0, r5
- bne _020D055C
- ldr r5, [sp, #0x14]
- add r1, r7, r6
- add r0, sp, #0x18
- mov r2, r5
- sub r1, r1, r5
- bl MI_CpuCopy8
- sub r6, r6, r5
- b _020D0570
-_020D055C:
- mov r0, sl
- mov r1, r4
- bl FSi_TranslateCommand
- cmp r0, #0x0
- beq _020D0524
-_020D0570:
- ldrh r5, [sp, #0xbc]
- cmp r5, #0x0
- bne _020D04F0
-_020D057C:
- mov r0, #0x0
- add sp, sp, #0xe4
- ldmia sp!, {r4-r11,lr}
- bx lr
- .balign 4
-_020D058C: .word 0x0210682C
-
- arm_func_start FSi_FindPathCommand
-FSi_FindPathCommand: ; 0x020D0590
- stmdb sp!, {r4-r11,lr}
- sub sp, sp, #0x9c
- mov r10, r0
- ldr r2, [r10, #0x40]
- ldr r9, [r10, #0x3c]
- mov r1, #0x2
- str r2, [sp, #0x0]
- bl FSi_TranslateCommand
- ldrb r1, [r9, #0x0]
- cmp r1, #0x0
- beq _020D0780
- mov r0, #0x2
- add r11, sp, #0x1c
- mov r4, #0x3
- mov r5, #0x1
- mov r6, #0x0
- str r0, [sp, #0x4]
-_020D05D4:
- mov r7, r6
- b _020D05E0
-_020D05DC:
- add r7, r7, #0x1
-_020D05E0:
- ldrb r8, [r9, r7]
- mov r0, r6
- cmp r8, #0x0
- beq _020D0600
- cmp r8, #0x2f
- beq _020D0600
- cmp r8, #0x5c
- movne r0, r5
-_020D0600:
- cmp r0, #0x0
- bne _020D05DC
- cmp r8, #0x0
- bne _020D061C
- ldr r0, [sp, #0x0]
- cmp r0, #0x0
- beq _020D0620
-_020D061C:
- mov r8, r5
-_020D0620:
- cmp r7, #0x0
- addeq sp, sp, #0x9c
- moveq r0, #0x1
- ldmeqia sp!, {r4-r11,lr}
- bxeq lr
- cmp r1, #0x2e
- bne _020D068C
- cmp r7, #0x1
- addeq r9, r9, #0x1
- beq _020D0764
- ldrb r0, [r9, #0x1]
- cmp r7, #0x2
- moveq r1, r5
- movne r1, r6
- cmp r0, #0x2e
- moveq r0, r5
- movne r0, r6
- ands r0, r1, r0
- beq _020D068C
- ldrh r0, [r10, #0x24]
- cmp r0, #0x0
- beq _020D0684
- ldr r1, [r10, #0x2c]
- mov r0, r10
- bl FSi_SeekDirDirect
-_020D0684:
- add r9, r9, #0x2
- b _020D0764
-_020D068C:
- cmp r7, #0x7f
- addgt sp, sp, #0x9c
- movgt r0, #0x1
- ldmgtia sp!, {r4-r11,lr}
- bxgt lr
- add r0, sp, #0x8
- str r0, [r10, #0x30]
- str r6, [r10, #0x34]
-_020D06AC:
- mov r0, r10
- mov r1, r4
- bl FSi_TranslateCommand
-_020D06B8:
- cmp r0, #0x0
- addne sp, sp, #0x9c
- movne r0, #0x1
- ldmneia sp!, {r4-r11,lr}
- bxne lr
- ldr r0, [sp, #0x14]
- cmp r8, r0
- bne _020D06AC
- ldr r0, [sp, #0x18]
- cmp r7, r0
- bne _020D06AC
- mov r0, r9
- mov r1, fp
- mov r2, r7
- bl FSi_StrNICmp
- cmp r0, #0x0
- bne _020D06AC
- cmp r8, #0x0
- beq _020D0728
- add r0, sp, #0x8
- add r3, sl, #0x30
- ldmia r0, {r0, r1, r2}
- stmia r3, {r0, r1, r2}
- ldr r1, [sp, #0x4]
- mov r0, sl
- add r9, r9, r7
- bl FSi_TranslateCommand
- b _020D0764
-_020D0728:
- ldr r0, [sp]
- cmp r0, #0x0
- addne sp, sp, #0x9c
- movne r0, #0x1
- ldmneia sp!, {r4-r11,lr}
- bxne lr
- ldr r3, [sl, #0x44]
- ldr r2, [sp, #0x8]
- ldr r1, [sp, #0xC]
- add sp, sp, #0x9c
- str r2, [r3]
- str r1, [r3, #0x4]
- mov r0, #0x0
- ldmia sp!, {r4-r11,lr}
- bx lr
-_020D0764:
- ldrb r0, [r9, #0x0]
- cmp r0, #0x0
- movne r0, r5
- moveq r0, r6
- ldrb r1, [r9, r0]!
- cmp r1, #0x0
- bne _020D05D4
-_020D0780:
- ldr r0, [sp, #0x0]
- cmp r0, #0x0
- moveq r0, #0x1
- addne r0, r10, #0x20
- ldrne r3, [r10, #0x44]
- ldmneia r0, {r0-r2}
- stmneia r3, {r0-r2}
- movne r0, #0x0
- add sp, sp, #0x9c
- ldmia sp!, {r4-r11,lr}
- bx lr
-
- arm_func_start FSi_ReadDirCommand
-FSi_ReadDirCommand: ; 0x020D07AC
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0xc
- mov r5, r0
- ldr r4, [r5, #0x30]
- ldr r1, [r5, #0x8]
- add r0, sp, #0x4
- str r1, [sp, #0x4]
- ldr r3, [r5, #0x28]
- add r1, sp, #0x0
- mov r2, #0x1
- str r3, [sp, #0x8]
- bl FSi_ReadTable
-_020D07DC:
- cmp r0, #0x0
- addne sp, sp, #0xC
- ldmneia sp!, {r4-r5,lr}
- bxne lr
- ldrb r1, [sp]
- and r2, r1, #0x7F
- mov r1, r1, asr #0x7
- str r2, [r4, #0x10]
- and r1, r1, #0x1
- str r1, [r4, #0xC]
- ldr r2, [r4, #0x10]
- cmp r2, #0x0
- addeq sp, sp, #0xC
- moveq r0, #0x1
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- ldr r1, [r5, #0x34]
- cmp r1, #0x0
- bne _020D0858
- add r0, sp, #0x4
- add r1, r4, #0x14
- bl FSi_ReadTable
- cmp r0, #0x0
- addne sp, sp, #0xC
- ldmneia sp!, {r4-r5,lr}
- bxne lr
- ldr r1, [r4, #0x10]
- mov r2, #0x0
- add r1, r4, r1
- strb r2, [r1, #0x14]
- b _020D0864
-_020D0858:
- ldr r1, [sp, #0x8]
- add r1, r1, r2
- str r1, [sp, #0x8]
-_020D0864:
- ldr r1, [r4, #0xC]
- cmp r1, #0x0
- beq _020D08B8
- add r0, sp, #0x4
- add r1, sp, #0x2
- mov r2, #0x2
- bl FSi_ReadTable
- cmp r0, #0x0
- addne sp, sp, #0xC
- ldmneia sp!, {r4-r5,lr}
- bxne lr
- ldr r2, [r5, #0x8]
- ldr r1, _020D08E8
- str r2, [r4]
- ldrh r3, [sp, #0x2]
- mov r2, #0x0
- and r1, r3, r1
- strh r1, [r4, #0x4]
- strh r2, [r4, #0x6]
- str r2, [r4, #0x8]
- b _020D08D4
-_020D08B8:
- ldr r1, [r5, #0x8]
- str r1, [r4]
- ldrh r1, [r5, #0x26]
- str r1, [r4, #0x4]
- ldrh r1, [r5, #0x26]
- add r1, r1, #0x1
- strh r1, [r5, #0x26]
-_020D08D4:
- ldr r1, [sp, #0x8]
- str r1, [r5, #0x28]
- add sp, sp, #0xC
- ldmia sp!, {r4-r5,lr}
- bx lr
-_020D08E8: .word 0x00000FFF
-
- arm_func_start FSi_SeekDirCommand
-FSi_SeekDirCommand: ; 0x020D08EC
- stmdb sp!, {r4-r6,lr}
- sub sp, sp, #0x10
- mov r6, r0
- ldr r5, [r6, #0x8]
- add r4, r6, #0x30
- str r5, [sp, #0x8]
- ldrh r1, [r4, #0x4]
- ldr r2, [r5, #0x34]
- add r0, sp, #0x8
- add r3, r2, r1, lsl #0x3
- add r1, sp, #0x0
- mov r2, #0x8
- str r3, [sp, #0xc]
- bl FSi_ReadTable
- movs r3, r0
- bne _020D0978
- add r12, r6, #0x20
- ldmia r4, {r0-r2}
- stmia r12, {r0-r2}
- ldrh r0, [r4, #0x6]
- cmp r0, #0x0
- bne _020D0968
- ldr r0, [r4, #0x8]
- cmp r0, #0x0
- bne _020D0968
- ldrh r0, [sp, #0x4]
- strh r0, [r6, #0x26]
- ldr r1, [r5, #0x34]
- ldr r0, [sp, #0x0]
- add r0, r1, r0
- str r0, [r6, #0x28]
-_020D0968:
- ldrh r1, [sp, #0x6]
- ldr r0, _020D0988 ; =0x00000FFF
- and r0, r1, r0
- str r0, [r6, #0x2c]
-_020D0978:
- mov r0, r3
- add sp, sp, #0x10
- ldmia sp!, {r4-r6,lr}
- bx lr
- .balign 4
-_020D0988: .word 0x00000FFF
-
- arm_func_start FSi_WriteFileCommand
-FSi_WriteFileCommand: ; 0x020D098C
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r2, [r0, #0x2c]
- ldr r3, [r0, #0x38]
- ldr lr, [r0, #0x8]
- ldr r1, [r0, #0x30]
- add r12, r2, r3
- str r12, [r0, #0x2c]
- ldr r12, [lr, #0x4c]
- mov r0, lr
- blx r12
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start FSi_ReadFileCommand
-FSi_ReadFileCommand: ; 0x020D09C4
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r2, [r0, #0x2c]
- ldr r3, [r0, #0x38]
- ldr lr, [r0, #0x8]
- ldr r1, [r0, #0x30]
- add r12, r2, r3
- str r12, [r0, #0x2c]
- ldr r12, [lr, #0x48]
- mov r0, lr
- blx r12
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start FSi_SeekDirDirect
-FSi_SeekDirDirect: ; 0x020D09FC
- ldr r3, [r0, #0xc]
- mov r2, #0x0
- orr r3, r3, #0x4
- str r3, [r0, #0xc]
- ldr r3, [r0, #0x8]
- ldr ip, _020D0A2C ; =FSi_TranslateCommand
- str r3, [r0, #0x30]
- str r2, [r0, #0x38]
- strh r2, [r0, #0x36]
- strh r1, [r0, #0x34]
- mov r1, #0x2
- bx r12
- .balign 4
-_020D0A2C: .word FSi_TranslateCommand
-
- arm_func_start FSi_ReadTable
-FSi_ReadTable:
- stmdb sp!, {r4-r8,lr}
- mov r7, r0
- ldr r5, [r7, #0x0]
- mov r6, r2
- ldr r2, [r5, #0x1c]
- mov r0, r5
- orr r2, r2, #0x200
- str r2, [r5, #0x1c]
- ldr r2, [r7, #0x4]
- ldr r4, [r5, #0x50]
- mov r3, r6
- blx r4
- cmp r0, #0x0
- beq _020D0A7C
- cmp r0, #0x1
- beq _020D0A7C
- cmp r0, #0x6
- beq _020D0A8C
- b _020D0AC8
-_020D0A7C:
- ldr r1, [r5, #0x1c]
- bic r1, r1, #0x200
- str r1, [r5, #0x1c]
- b _020D0AC8
-_020D0A8C:
- bl OS_DisableInterrupts
- ldr r1, [r5, #0x1c]
- mov r4, r0
- ands r0, r1, #0x200
- beq _020D0AB8
- add r8, r5, #0xc
-_020D0AA4:
- mov r0, r8
- bl OS_SleepThread
- ldr r0, [r5, #0x1c]
- ands r0, r0, #0x200
- bne _020D0AA4
-_020D0AB8:
- mov r0, r4
- bl OS_RestoreInterrupts
- ldr r0, [r5, #0x24]
- ldr r0, [r0, #0x14]
-_020D0AC8:
- ldr r1, [r7, #0x4]
- add r1, r1, r6
- str r1, [r7, #0x4]
- ldmia sp!, {r4-r8,lr}
- bx lr
-
- arm_func_start FSi_StrNICmp
-FSi_StrNICmp: ; 0x020D0ADC
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- cmp r2, #0x0
- mov lr, #0x0
- bls _020D0B30
-_020D0AF0:
- ldrb r12, [r0, lr]
- ldrb r3, [r1, lr]
- sub r12, r12, #0x41
- cmp r12, #0x19
- sub r3, r3, #0x41
- addls r12, r12, #0x20
- cmp r3, #0x19
- addls r3, r3, #0x20
- cmp r12, r3
- addne sp, sp, #0x4
- subne r0, r12, r3
- ldmneia sp!, {lr}
- bxne lr
- add lr, lr, #0x1
- cmp lr, r2
- blo _020D0AF0
-_020D0B30:
- mov r0, #0x0
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start FS_NotifyArchiveAsyncEnd
-FS_NotifyArchiveAsyncEnd: ; 0x020D0B40
- stmdb sp!, {r4-r6,lr}
- mov r4, r0
- ldr r0, [r4, #0x1c]
- mov r6, r1
- ands r0, r0, #0x100
- beq _020D0B8C
- ldr r2, [r4, #0x1c]
- ldr r0, [r4, #0x24]
- bic r2, r2, #0x100
- str r2, [r4, #0x1c]
- bl FSi_ReleaseCommand
- mov r0, r4
- bl FSi_NextCommand
-_020D0B74:
- cmp r0, #0x0
- ldmeqia sp!, {r4-r6,lr}
- bxeq lr
- bl FSi_ExecuteAsyncCommand
- ldmia sp!, {r4-r6,lr}
- bx lr
-_020D0B8C:
- ldr r5, [r4, #0x24]
- bl OS_DisableInterrupts
- str r6, [r5, #0x14]
- ldr r1, [r4, #0x1c]
- mov r5, r0
- bic r1, r1, #0x200
- add r0, r4, #0xc
- str r1, [r4, #0x1c]
- bl OS_WakeupThread
- mov r0, r5
- bl OS_RestoreInterrupts
- ldmia sp!, {r4-r6,lr}
- bx lr
-
- arm_func_start FS_SetArchiveProc
-FS_SetArchiveProc: ; 0x020D0BC0
- cmp r2, #0x0
- moveq r1, #0x0
- beq _020D0BD4
- cmp r1, #0x0
- moveq r2, #0x0
-_020D0BD4:
- str r1, [r0, #0x54]
- str r2, [r0, #0x58]
- bx lr
-
- arm_func_start FS_ResumeArchive
-FS_ResumeArchive:
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- mov r4, r0
- mov r6, #0x0
- bl OS_DisableInterrupts
- ldr r1, [r4, #0x1c]
- mov r5, r0
- ands r0, r1, #0x8
- movne r0, #0x1
- moveq r0, r6
- cmp r0, #0x0
- moveq r7, #0x1
- movne r7, #0x0
- cmp r7, #0x0
- bne _020D0C34
- ldr r1, [r4, #0x1c]
- mov r0, r4
- bic r1, r1, #0x8
- str r1, [r4, #0x1c]
- bl FSi_NextCommand
- mov r6, r0
-_020D0C34:
- mov r0, r5
- bl OS_RestoreInterrupts
-_020D0C3C:
- cmp r6, #0x0
- beq _020D0C4C
- mov r0, r6
- bl FSi_ExecuteAsyncCommand
-_020D0C4C:
- mov r0, r7
- add sp, sp, #0x4
- ldmia sp!, {r4-r7, lr}
- bx lr
-
- arm_func_start FS_SuspendArchive
-FS_SuspendArchive: ; 0x020D0C5C
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- mov r6, r0
- bl OS_DisableInterrupts
- ldr r1, [r6, #0x1c]
- mov r4, r0
- ands r0, r1, #0x8
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- moveq r5, #0x1
- movne r5, #0x0
- cmp r5, #0x0
- beq _020D0CD4
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x10
- beq _020D0CC8
- ldr r0, [r6, #0x1c]
- orr r0, r0, #0x40
- str r0, [r6, #0x1c]
- add r7, r6, #0x14
-_020D0CB0:
- mov r0, r7
- bl OS_SleepThread
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x40
- bne _020D0CB0
- b _020D0CD4
-_020D0CC8:
- ldr r0, [r6, #0x1c]
- orr r0, r0, #0x8
- str r0, [r6, #0x1c]
-_020D0CD4:
- mov r0, r4
- bl OS_RestoreInterrupts
- mov r0, r5
- add sp, sp, #0x4
- ldmia sp!, {r4-r7,lr}
- bx lr
-
- arm_func_start FS_UnloadArchiveTables
-FS_UnloadArchiveTables: ; 0x020D0CEC
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x4
- mov r5, r0
- ldr r0, [r5, #0x1c]
- mov r4, #0x0
- ands r0, r0, #0x2
- movne r0, #0x1
- moveq r0, r4
- cmp r0, #0x0
- beq _020D0D74
- mov r0, r5
- bl FS_SuspendArchive
- ldr r1, [r5, #0x1c]
- ands r1, r1, #0x4
- movne r1, #0x1
- moveq r1, #0x0
- cmp r1, #0x0
- beq _020D0D64
- ldr r2, [r5, #0x1c]
- mov r1, #0x0
- bic r2, r2, #0x4
- str r2, [r5, #0x1c]
- ldr r4, [r5, #0x44]
- str r1, [r5, #0x44]
- ldr r1, [r5, #0x3c]
- str r1, [r5, #0x2c]
- ldr r1, [r5, #0x40]
- str r1, [r5, #0x34]
- ldr r1, [r5, #0x48]
- str r1, [r5, #0x50]
-_020D0D64:
- cmp r0, #0x0
- beq _020D0D74
- mov r0, r5
- bl FS_ResumeArchive
-_020D0D74:
- mov r0, r4
- add sp, sp, #0x4
- ldmia sp!, {r4-r5,lr}
- bx lr
-
- arm_func_start FUN_020D0D84
-FUN_020D0D84: ; 0x020D0D84
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4c
- mov r7, r0
- ldr r3, [r7, #0x30]
- ldr r0, [r7, #0x38]
- mov r6, r1
- add r0, r3, r0
- add r0, r0, #0x20
- add r0, r0, #0x1f
- bic r5, r0, #0x1f
- cmp r5, r2
- bhi _020D0E9C
- add r1, r6, #0x1f
- add r0, sp, #0x4
- bic r4, r1, #0x1f
- bl FS_InitFile
- ldr r2, [r7, #0x2c]
- mvn r0, #0x0
- str r0, [sp, #0x0]
- ldr r3, [r7, #0x30]
- add r0, sp, #0x4
- mov r1, r7
- add r3, r2, r3
- bl FS_OpenFileDirect
-_020D0DE4:
- cmp r0, #0x0
- beq _020D0E1C
- ldr r2, [r7, #0x30]
- add r0, sp, #0x4
- mov r1, r4
- bl FS_ReadFile
- cmp r0, #0x0
- bge _020D0E14
- ldr r2, [r7, #0x30]
- mov r0, r4
- mov r1, #0x0
- bl MI_CpuFill8
-_020D0E14:
- add r0, sp, #0x4
- bl FS_CloseFile
-_020D0E1C:
- str r4, [r7, #0x2C]
- ldr ip, [r7, #0x30]
- ldr r2, [r7, #0x34]
- mvn r0, #0x0
- str r0, [sp]
- ldr r3, [r7, #0x38]
- add r0, sp, #0x4
- mov r1, r7
- add r3, r2, r3
- add r4, r4, ip
- bl FS_OpenFileDirect
- cmp r0, #0x0
- beq _020D0E80
- ldr r2, [r7, #0x38]
- add r0, sp, #0x4
- mov r1, r4
- bl FS_ReadFile
- cmp r0, #0x0
- bge _020D0E78
- ldr r2, [r7, #0x38]
- mov r0, r4
- mov r1, #0x0
- bl MI_CpuFill8
-_020D0E78:
- add r0, sp, #0x4
- bl FS_CloseFile
-_020D0E80:
- str r4, [r7, #0x34]
- ldr r0, _020D0EAC
- str r6, [r7, #0x44]
- str r0, [r7, #0x50]
- ldr r0, [r7, #0x1C]
- orr r0, r0, #0x4
- str r0, [r7, #0x1C]
-_020D0E9C:
- mov r0, r5
- add sp, sp, #0x4C
- ldmia sp!, {r4-r7,lr}
- bx lr
-_020D0EAC:
- .word FSi_ReadMemoryCore
-
- arm_func_start FUN_020D0EB0
-FUN_020D0EB0: ; 0x020D0EB0
- stmdb sp!, {r4-r8,lr}
- mov r5, r0
- bl OS_DisableInterrupts
- ldr r1, [r5, #0x1c]
- mov r4, r0
- ands r0, r1, #0x2
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- beq _020D0F64
- mov r0, r5
- ldr r1, [r5, #0x1c]
- bl FS_SuspendArchive
- ldr r1, [r5, #0x1c]
- mov r7, r0
- orr r0, r1, #0x80
- str r0, [r5, #0x1c]
- ldr r0, [r5, #0x24]
- cmp r0, #0x0
- beq _020D0F1C
- mov r6, #0x3
-_020D0F04:
- ldr r8, [r0, #0x4]
- mov r1, r6
- bl FSi_ReleaseCommand
- mov r0, r8
- cmp r8, #0x0
- bne _020D0F04
-_020D0F1C:
- mov r0, #0x0
- str r0, [r5, #0x24]
- cmp r7, #0x0
- beq _020D0F34
- mov r0, r5
- bl FS_ResumeArchive
-_020D0F34:
- mov r0, #0x0
- str r0, [r5, #0x28]
- str r0, [r5, #0x2c]
- str r0, [r5, #0x30]
- str r0, [r5, #0x34]
- str r0, [r5, #0x38]
- str r0, [r5, #0x40]
- ldr r0, [r5, #0x40]
- str r0, [r5, #0x3c]
- ldr r0, [r5, #0x1c]
- bic r0, r0, #0xa2
- str r0, [r5, #0x1c]
-_020D0F64:
- mov r0, r4
- bl OS_RestoreInterrupts
- mov r0, #0x1
- ldmia sp!, {r4-r8,lr}
- bx lr
-
- arm_func_start FS_LoadArchive
-FS_LoadArchive: ; 0x020D0F78
- str r1, [r0, #0x28]
- str r3, [r0, #0x30]
- str r2, [r0, #0x3c]
- ldr r1, [r0, #0x3c]
- ldr r2, [sp, #0x4]
- str r1, [r0, #0x2c]
- str r2, [r0, #0x38]
- ldr r1, [sp, #0x0]
- ldr r2, [sp, #0x8]
- str r1, [r0, #0x40]
- ldr r1, [r0, #0x40]
- cmp r2, #0x0
- str r1, [r0, #0x34]
- ldreq r2, _020D0FE8 ; =FSi_ReadMemCallback
- ldr r1, [sp, #0xc]
- str r2, [r0, #0x48]
- cmp r1, #0x0
- ldreq r1, _020D0FEC ; =FSi_WriteMemCallback
- str r1, [r0, #0x4c]
- ldr r2, [r0, #0x48]
- mov r1, #0x0
- str r2, [r0, #0x50]
- str r1, [r0, #0x44]
- ldr r1, [r0, #0x1c]
- orr r1, r1, #0x2
- str r1, [r0, #0x1c]
- mov r0, #0x1
- bx lr
- .balign 4
-_020D0FE8: .word FSi_ReadMemCallback
-_020D0FEC: .word FSi_WriteMemCallback
-
- arm_func_start FUN_020D0FF0
-FUN_020D0FF0: ; 0x020D0FF0
- stmdb sp!, {r4,lr}
- mov r4, r0
- ldr r0, [r4, #0x0]
- cmp r0, #0x0
- ldmeqia sp!, {r4,lr}
- bxeq lr
- bl OS_DisableInterrupts
- ldr r2, [r4, #0x4]
- mov r3, #0x0
- cmp r2, #0x0
- ldrne r1, [r4, #0x8]
- strne r1, [r2, #0x8]
- ldr r2, [r4, #0x8]
- cmp r2, #0x0
- ldrne r1, [r4, #0x4]
- strne r1, [r2, #0x4]
- str r3, [r4, #0x0]
- str r3, [r4, #0x8]
- ldr r1, [r4, #0x8]
- ldr r2, _020D1080 ; =0x021D53EC
- str r1, [r4, #0x4]
- ldr r1, [r4, #0x1c]
- bic r1, r1, #0x1
- str r1, [r4, #0x1c]
- ldr r1, [r2, #0x0]
- cmp r1, r4
- bne _020D1074
- ldr r1, _020D1084 ; =0x021D53E8
- str r3, [r2, #0x8]
- ldr r1, [r1, #0x0]
- strh r3, [r2, #0x6]
- str r1, [r2, #0x0]
- strh r3, [r2, #0x4]
-_020D1074:
- bl OS_RestoreInterrupts
- ldmia sp!, {r4,lr}
- bx lr
- .balign 4
-_020D1080: .word 0x021D53EC
-_020D1084: .word 0x021D53E8
-
- arm_func_start FS_RegisterArchiveName
-FS_RegisterArchiveName: ; 0x020D1088
- stmdb sp!, {r4-r8,lr}
- mov r6, r1
- mov r5, r2
- mov r7, r0
- mov r8, #0x0
- bl OS_DisableInterrupts
- mov r4, r0
- mov r0, r6
- mov r1, r5
- bl FS_FindArchive
-_020D10B0:
- cmp r0, #0x0
- bne _020D112C
- ldr r1, _020D1140
- ldr r2, [r1]
- cmp r2, #0x0
- bne _020D10E8
- ldr r0, _020D1144
- mov r2, r8
- str r7, [r1]
- str r7, [r0]
- str r2, [r0, #0x8]
- strh r2, [r0, #0x6]
- strh r2, [r0, #0x4]
- b _020D110C
-_020D10E8:
- ldr r0, [r2, #0x4]
- cmp r0, #0x0
- beq _020D1104
-_020D10F4:
- mov r2, r0
- ldr r0, [r0, #0x4]
- cmp r0, #0x0
- bne _020D10F4
-_020D1104:
- str r7, [r2, #0x4]
- str r2, [r7, #0x8]
-_020D110C:
- mov r0, r6
- mov r1, r5
- bl FSi_GetPackedName
- str r0, [r7]
- ldr r0, [r7, #0x1C]
- mov r8, #0x1
- orr r0, r0, #0x1
- str r0, [r7, #0x1C]
-_020D112C:
- mov r0, r4
- bl OS_RestoreInterrupts
- mov r0, r8
- ldmia sp!, {r4-r8,lr}
- bx lr
-_020D1140: .word 0x021D53E8
-_020D1144: .word 0x021D53EC
-
- arm_func_start FS_FindArchive
-FS_FindArchive:
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x4
- bl FSi_GetPackedName
- mov r5, r0
- bl OS_DisableInterrupts
- ldr r1, _020D1194 ; =0x021D53E8
- ldr r4, [r1, #0x0]
- b _020D116C
-_020D1168:
- ldr r4, [r4, #0x4]
-_020D116C:
- cmp r4, #0x0
- beq _020D1180
- ldr r1, [r4, #0x0]
- cmp r1, r5
- bne _020D1168
-_020D1180:
- bl OS_RestoreInterrupts
- mov r0, r4
- add sp, sp, #0x4
- ldmia sp!, {r4-r5,lr}
- bx lr
- .balign 4
-_020D1194: .word 0x021D53E8
-
- arm_func_start FS_InitArchive
-FS_InitArchive: ; 0x020D1198
- stmdb sp!, {r4,lr}
- mov r1, #0x0
- mov r2, #0x5c
- mov r4, r0
- bl MI_CpuFill8
- mov r1, #0x0
- str r1, [r4, #0x10]
- ldr r0, [r4, #0x10]
- str r0, [r4, #0xc]
- str r1, [r4, #0x18]
- ldr r0, [r4, #0x18]
- str r0, [r4, #0x14]
- ldmia sp!, {r4,lr}
- bx lr
-
- arm_func_start FSi_SendCommand
-FSi_SendCommand:
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- mov r7, r0
- ldr r6, [r7, #0x8]
- mov r2, #0x1
- str r1, [r7, #0x10]
- mov r0, #0x2
- str r0, [r7, #0x14]
- ldr r0, [r7, #0xc]
- mov r5, r2, lsl r1
- orr r0, r0, #0x1
- str r0, [r7, #0xc]
- bl OS_DisableInterrupts
- ldr r1, [r6, #0x1c]
- mov r4, r0
- ands r0, r1, #0x80
- beq _020D1238
- mov r0, r7
- mov r1, #0x3
- bl FSi_ReleaseCommand
- mov r0, r4
- bl OS_RestoreInterrupts
- add sp, sp, #0x4
- mov r0, #0x0
- ldmia sp!, {r4-r7,lr}
- bx lr
-_020D1238:
- ands r0, r5, #0x1fc
- ldrne r0, [r7, #0xc]
- add r2, r6, #0x20
- orrne r0, r0, #0x4
- strne r0, [r7, #0xc]
- ldr r1, [r7, #0x0]
- ldr r0, [r7, #0x4]
- cmp r1, #0x0
- strne r0, [r1, #0x4]
- cmp r0, #0x0
- strne r1, [r0, #0x0]
- ldr r0, [r2, #0x4]
- cmp r0, #0x0
- beq _020D1280
-_020D1270:
- mov r2, r0
- ldr r0, [r0, #0x4]
- cmp r0, #0x0
- bne _020D1270
-_020D1280:
- str r7, [r2, #0x4]
- str r2, [r7, #0x0]
- mov r1, #0x0
- str r1, [r7, #0x4]
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x8
- movne r1, #0x1
- cmp r1, #0x0
- bne _020D132C
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x10
- bne _020D132C
- ldr r1, [r6, #0x1c]
- mov r0, r4
- orr r1, r1, #0x10
- str r1, [r6, #0x1c]
- bl OS_RestoreInterrupts
- ldr r0, [r6, #0x58]
- ands r0, r0, #0x200
- beq _020D12E0
- ldr r2, [r6, #0x54]
- mov r0, r7
- mov r1, #0x9
- blx r2
-_020D12E0:
- bl OS_DisableInterrupts
- ldr r1, [r7, #0xc]
- orr r1, r1, #0x40
- str r1, [r7, #0xc]
- ldr r1, [r7, #0xc]
- ands r1, r1, #0x4
- movne r1, #0x1
- moveq r1, #0x0
- cmp r1, #0x0
- bne _020D1324
- bl OS_RestoreInterrupts
- mov r0, r7
- bl FSi_ExecuteAsyncCommand
- add sp, sp, #0x4
- mov r0, #0x1
- ldmia sp!, {r4-r7,lr}
- bx lr
-_020D1324:
- bl OS_RestoreInterrupts
- b _020D1378
-_020D132C:
- ldr r0, [r7, #0xc]
- ands r0, r0, #0x4
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- bne _020D135C
- mov r0, r4
- bl OS_RestoreInterrupts
- add sp, sp, #0x4
- mov r0, #0x1
- ldmia sp!, {r4-r7,lr}
- bx lr
-_020D135C:
- add r0, r7, #0x18
- bl OS_SleepThread
- ldr r0, [r7, #0xc]
- ands r0, r0, #0x40
- beq _020D135C
- mov r0, r4
- bl OS_RestoreInterrupts
-_020D1378:
- mov r0, r7
- bl FSi_ExecuteSyncCommand
- add sp, sp, #0x4
- ldmia sp!, {r4-r7,lr}
- bx lr
-
- arm_func_start FSi_ExecuteSyncCommand
-FSi_ExecuteSyncCommand: ; 0x020D138C
- stmdb sp!, {r4,lr}
- mov r4, r0
- ldr r1, [r4, #0x10]
- bl FSi_TranslateCommand
- mov r1, r0
- mov r0, r4
- bl FSi_ReleaseCommand
- ldr r0, [r4, #0x8]
- bl FSi_NextCommand
-_020D13B0:
- cmp r0, #0x0
- beq _020D13BC
- bl FSi_ExecuteAsyncCommand
-_020D13BC:
- ldr r0, [r4, #0x14]
- cmp r0, #0x0
- moveq r0, #0x1
- movne r0, #0x0
- ldmia sp!, {r4,lr}
- bx lr
-
- arm_func_start FSi_ExecuteAsyncCommand
-FSi_ExecuteAsyncCommand: ; 0x020D13D4
- stmdb sp!, {r4-r8,lr}
- movs r6, r0
- ldr r5, [r6, #0x8]
- ldmeqia sp!, {r4-r8,lr}
- bxeq lr
- mov r7, #0x0
- mov r8, #0x1
-_020D13F0:
- bl OS_DisableInterrupts
- ldr r1, [r6, #0xc]
- mov r4, r0
- orr r0, r1, #0x40
- str r0, [r6, #0xc]
- ldr r0, [r6, #0xc]
- ands r0, r0, #0x4
- movne r0, r8
- moveq r0, r7
- cmp r0, #0x0
- beq _020D1434
- add r0, r6, #0x18
- bl OS_WakeupThread
- mov r0, r4
- bl OS_RestoreInterrupts
- ldmia sp!, {r4-r8,lr}
- bx lr
-_020D1434:
- ldr r1, [r6, #0xc]
- mov r0, r4
- orr r1, r1, #0x8
- str r1, [r6, #0xc]
- bl OS_RestoreInterrupts
- ldr r1, [r6, #0x10]
- mov r0, r6
- bl FSi_TranslateCommand
- cmp r0, #0x6
- ldmeqia sp!, {r4-r8,lr}
- bxeq lr
- mov r0, r5
- bl FSi_NextCommand
- movs r6, r0
- bne _020D13F0
- ldmia sp!, {r4-r8,lr}
- bx lr
-
- arm_func_start FSi_NextCommand
-FSi_NextCommand:
- stmdb sp!, {r4-r9,lr}
- sub sp, sp, #0x4c
- mov r6, r0
- bl OS_DisableInterrupts
- ldr r1, [r6, #0x1c]
- mov r5, r0
- ands r0, r1, #0x20
- beq _020D1500
- ldr r0, [r6, #0x1c]
- bic r0, r0, #0x20
- str r0, [r6, #0x1c]
- ldr r0, [r6, #0x24]
- cmp r0, #0x0
- beq _020D1500
- mov r8, #0x0
- mov r9, #0x1
- mov r7, #0x3
-_020D14BC:
- ldr r1, [r0, #0xc]
- ldr r4, [r0, #0x4]
- ands r1, r1, #0x2
- movne r1, r9
- moveq r1, r8
- cmp r1, #0x0
- beq _020D14F4
- ldr r1, [r6, #0x24]
- cmp r1, r0
- mov r1, r7
- streq r4, [r6, #0x24]
- bl FSi_ReleaseCommand
-_020D14EC:
- cmp r4, #0x0
- ldreq r4, [r6, #0x24]
-_020D14F4:
- mov r0, r4
- cmp r4, #0x0
- bne _020D14BC
-_020D1500:
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x40
- bne _020D15EC
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x8
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- bne _020D15EC
- ldr r4, [r6, #0x24]
- cmp r4, #0x0
- beq _020D15EC
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x10
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- moveq r7, #0x1
- movne r7, #0x0
- cmp r7, #0x0
- ldrne r0, [r6, #0x1c]
- orrne r0, r0, #0x10
- strne r0, [r6, #0x1c]
- mov r0, r5
- bl OS_RestoreInterrupts
-_020D1564:
- cmp r7, #0x0
- beq _020D1588
- ldr r0, [r6, #0x58]
- ands r0, r0, #0x200
- beq _020D1588
- ldr r2, [r6, #0x54]
- mov r0, r4
- mov r1, #0x9
- blx r2
-_020D1588:
- bl OS_DisableInterrupts
- ldr r1, [r4, #0xC]
- mov r5, r0
- orr r0, r1, #0x40
- str r0, [r4, #0xC]
- ldr r0, [r4, #0xC]
- ands r0, r0, #0x4
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- beq _020D15D4
- add r0, r4, #0x18
- bl OS_WakeupThread
- mov r0, r5
- bl OS_RestoreInterrupts
- add sp, sp, #0x4c
- mov r0, #0x0
- ldmia sp!, {r4-r9, lr}
- bx lr
-_020D15D4:
- mov r0, r5
- bl OS_RestoreInterrupts
- add sp, sp, #0x4c
- mov r0, r4
- ldmia sp!, {r4-r9, lr}
- bx lr
-_020D15EC:
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x10
- beq _020D162C
- ldr r0, [r6, #0x1c]
- bic r0, r0, #0x10
- str r0, [r6, #0x1c]
- ldr r0, [r6, #0x58]
- ands r0, r0, #0x400
- beq _020D162C
- add r0, sp, #0x0
- bl FS_InitFile
- str r6, [sp, #0x8]
- ldr r2, [r6, #0x54]
- add r0, sp, #0x0
- mov r1, #0xa
- blx r2
-_020D162C:
- ldr r0, [r6, #0x1c]
- ands r0, r0, #0x40
- beq _020D1658
- ldr r1, [r6, #0x1c]
- add r0, r6, #0x14
- bic r1, r1, #0x40
- str r1, [r6, #0x1c]
- ldr r1, [r6, #0x1c]
- orr r1, r1, #0x8
- str r1, [r6, #0x1c]
- bl OS_WakeupThread
-_020D1658:
- mov r0, r5
- bl OS_RestoreInterrupts
-_020D1660:
- mov r0, #0x0
- add sp, sp, #0x4c
- ldmia sp!, {r4-r9, lr}
- bx lr
-
- arm_func_start FSi_ReadMemoryCore
-FSi_ReadMemoryCore: ; 0x020D1670
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- mov r0, r2
- mov r2, r3
- bl MI_CpuCopy8
-_020D1684:
- mov r0, #0x0
- add sp, sp, #0x4
- ldmfd sp!, {lr}
- bx lr
-
- arm_func_start FSi_WriteMemCallback
-FSi_WriteMemCallback: ; 0x020D1694
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r12, [r0, #0x28]
- mov r0, r1
- add r1, r12, r2
- mov r2, r3
- bl MI_CpuCopy8
-_020D16B0:
- mov r0, #0x0
- add sp, sp, #0x4
- ldmfd sp!, {lr}
- bx lr
-
- arm_func_start FSi_ReadMemCallback
-FSi_ReadMemCallback: ; 0x020D16C0
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r0, [r0, #0x28]
- add r0, r0, r2
- mov r2, r3
- bl MI_CpuCopy8
-_020D16D8:
- mov r0, #0x0
- add sp, sp, #0x4
- ldmfd sp!, {lr}
- bx lr
-
- arm_func_start FSi_GetPackedName
-FSi_GetPackedName: ; 0x020D16E8
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- cmp r1, #0x3
- mov lr, #0x0
- bgt _020D173C
- mov r12, lr
- cmp r1, #0x0
- ble _020D173C
- mov r3, lr
-_020D170C:
- ldrb r2, [r0, r12]
- cmp r2, #0x0
- beq _020D173C
- sub r2, r2, #0x41
- cmp r2, #0x19
- addls r2, r2, #0x61
- addhi r2, r2, #0x41
- add r12, r12, #0x1
- orr lr, lr, r2, lsl r3
- cmp r12, r1
- add r3, r3, #0x8
- blt _020D170C
-_020D173C:
- mov r0, lr
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start FS_ChangeDir
-FS_ChangeDir: ; 0x020D174C
- stmdb sp!, {r4,lr}
- sub sp, sp, #0x58
- mov r4, r0
- add r0, sp, #0xc
- bl FS_InitFile
- add r0, sp, #0xc
- add r3, sp, #0x0
- mov r1, r4
- mov r2, #0x0
- bl FSi_FindPath
-_020D1774:
- cmp r0, #0x0
- moveq r0, #0x0
- addne r0, sp, #0x0
- ldrne r3, _020D179C
- ldmneia r0, {r0, r1, r2}
- stmneia r3, {r0, r1, r2}
- movne r0, #0x1
- add sp, sp, #0x58
- ldmia sp!, {r4, lr}
- bx lr
-_020D179C: .word 0x021D53EC
-
- arm_func_start FS_SeekFile
-FS_SeekFile: ; 0x020D17A0
- cmp r2, #0x0
- beq _020D17BC
- cmp r2, #0x1
- beq _020D17C8
- cmp r2, #0x2
- beq _020D17D4
- b _020D17E0
-_020D17BC:
- ldr r2, [r0, #0x24]
- add r1, r1, r2
- b _020D17E8
-_020D17C8:
- ldr r2, [r0, #0x2c]
- add r1, r1, r2
- b _020D17E8
-_020D17D4:
- ldr r2, [r0, #0x28]
- add r1, r1, r2
- b _020D17E8
-_020D17E0:
- mov r0, #0x0
- bx lr
-_020D17E8:
- ldr r2, [r0, #0x24]
- cmp r1, r2
- movlt r1, r2
- ldr r2, [r0, #0x28]
- cmp r1, r2
- movgt r1, r2
- str r1, [r0, #0x2c]
- mov r0, #0x1
- bx lr
-
- arm_func_start FS_ReadFile
-FS_ReadFile: ; 0x020D180C
- ldr ip, _020D1818 ; =FUN_020D1AAC
- mov r3, #0x0
- bx r12
- .balign 4
-_020D1818: .word FUN_020D1AAC
-
- arm_func_start FS_ReadFileAsync
-FS_ReadFileAsync: ; 0x020D181C
- ldr ip, _020D1828 ; =FUN_020D1AAC
- mov r3, #0x1
- bx r12
- .balign 4
-_020D1828: .word FUN_020D1AAC
-
- arm_func_start FS_WaitAsync
-FS_WaitAsync: ; 0x020D182C
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- mov r6, r0
- mov r5, #0x0
- bl OS_DisableInterrupts
- ldr r1, [r6, #0xc]
- mov r4, r0
- ands r0, r1, #0x1
- movne r0, #0x1
- moveq r0, r5
- cmp r0, #0x0
- beq _020D18BC
- ldr r0, [r6, #0xc]
- ands r0, r0, #0x44
- moveq r5, #0x1
- movne r5, #0x0
- cmp r5, #0x0
- beq _020D189C
- ldr r0, [r6, #0xc]
- orr r0, r0, #0x4
- str r0, [r6, #0xc]
- add r7, r6, #0x18
-_020D1884:
- mov r0, r7
- bl OS_SleepThread
- ldr r0, [r6, #0xc]
- ands r0, r0, #0x40
- beq _020D1884
- b _020D18BC
-_020D189C:
- add r0, r6, #0x18
- bl OS_SleepThread
- ldr r0, [r6, #0xc]
- ands r0, r0, #0x1
- movne r0, #0x1
- moveq r0, #0x0
- cmp r0, #0x0
- bne _020D189C
-_020D18BC:
- mov r0, r4
- bl OS_RestoreInterrupts
-_020D18C4:
- cmp r5, #0x0
- beq _020D18E0
- mov r0, r6
- bl FSi_ExecuteSyncCommand
- add sp, sp, #4
- ldmia sp!, {r4-r7,lr}
- bx lr
-_020D18E0:
- ldr r0, [r6, #0x14]
- cmp r0, #0x0
- moveq r0, #0x1
- movne r0, #0x0
- add sp, sp, #0x4
- ldmia sp!, {r4-r7,lr}
- bx lr
-
- arm_func_start FS_CloseFile
-FS_CloseFile: ; 0x020D18FC
- stmdb sp!, {r4,lr}
- mov r1, #0x8
- mov r4, r0
- bl FSi_SendCommand
-_020D190C:
- cmp r0, #0x0
- moveq r0, #0x0
- ldmeqia sp!, {r4,lr}
- bxeq lr
- mov r0, #0x0
- str r0, [r4, #0x8]
- mov r0, #0xE
- str r0, [r4, #0x10]
- ldr r1, [r4, #0xC]
- mov r0, #0x1
- bic r1, r1, #0x30
- str r1, [r4, #0xC]
- ldmia sp!, {r4,lr}
- bx lr
-
- arm_func_start FS_OpenFile
-FS_OpenFile: ; 0x020D1944
- stmdb sp!, {r4,lr}
- sub sp, sp, #0x8
- mov r4, r0
- add r0, sp, #0x0
- bl FS_ConvertPathToFileID
-_020D1958:
- cmp r0, #0x0
- beq _020D1984
- add r1, sp, #0x0
- mov r0, r4
- ldmia r1, {r1, r2}
- bl FS_OpenFileFast
- cmp r0, #0x0
- addne sp, sp, #0x8
- movne r0, #0x1
- ldmneia sp!, {r4, lr}
- bxne lr
-_020D1984:
- mov r0, #0x0
- add sp, sp, #0x8
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start FS_OpenFileFast
-FS_OpenFileFast:
- stmdb sp!, {r0-r3}
- stmdb sp!, {r4,lr}
- ldr r1, [sp, #0xc]
- mov r4, r0
- cmp r1, #0x0
- moveq r0, #0x0
- ldmeqia sp!, {r4,lr}
- addeq sp, sp, #0x10
- bxeq lr
- str r1, [r4, #0x8]
- ldr r3, [sp, #0xc]
- ldr r2, [sp, #0x10]
- mov r1, #0x6
- str r3, [r4, #0x30]
- str r2, [r4, #0x34]
- bl FSi_SendCommand
-_020D19D4:
- cmp r0, #0x0
- moveq r0, #0x0
- ldmeqia sp!, {r4, lr}
- addeq sp, sp, #0x10
- bxeq lr
- ldr r1, [r4, #0xC]
- mov r0, #0x1
- orr r1, r1, #0x10
- str r1, [r4, #0xC]
- ldr r1, [r4, #0xC]
- bic r1, r1, #0x20
- str r1, [r4, #0xC]
- ldmia sp!, {r4, lr}
- add sp, sp, #0x10
- bx lr
-
- arm_func_start FS_OpenFileDirect
-FS_OpenFileDirect:
- stmdb sp!, {r4,lr}
- mov r4, r0
- str r1, [r4, #0x8]
- ldr r12, [sp, #0x8]
- mov r1, #0x7
- str r12, [r4, #0x38]
- str r2, [r4, #0x30]
- str r3, [r4, #0x34]
- bl FSi_SendCommand
-_020D1A34:
- cmp r0, #0x0
- moveq r0, #0x0
- ldmeqia sp!, {r4, lr}
- bxeq lr
- ldr r1, [r4, #0xC]
- mov r0, #0x1
- orr r1, r1, #0x10
- str r1, [r4, #0xC]
- ldr r1, [r4, #0xC]
- bic r1, r1, #0x20
- str r1, [r4, #0xC]
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start FS_ConvertPathToFileID
-FS_ConvertPathToFileID:
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x4c
- mov r5, r0
- add r0, sp, #0x0
- mov r4, r1
- bl FS_InitFile
-_020D1A80:
- add r0, sp, #0x0
- mov r1, r4
- mov r2, r5
- mov r3, #0x0
- bl FSi_FindPath
- cmp r0, #0x0
- movne r0, #0x1
- moveq r0, #0x0
- add sp, sp, #0x4C
- ldmia sp!, {r4-r5, lr}
- bx lr
-
- arm_func_start FUN_020D1AAC
-FUN_020D1AAC: ; 0x020D1AAC
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- mov r7, r0
- ldr r4, [r7, #0x2c]
- ldr r0, [r7, #0x28]
- mov r6, r2
- str r1, [r7, #0x30]
- sub r0, r0, r4
- cmp r6, r0
- movgt r6, r0
- cmp r6, #0x0
- movlt r6, #0x0
- str r2, [r7, #0x34]
- mov r5, r3
- str r6, [r7, #0x38]
- cmp r5, #0x0
- ldreq r0, [r7, #0xc]
- mov r1, #0x0
- orreq r0, r0, #0x4
- streq r0, [r7, #0xc]
- mov r0, r7
- bl FSi_SendCommand
-_020D1B04:
- cmp r5, #0x0
- bne _020D1B24
- mov r0, r7
- bl FS_WaitAsync
- cmp r0, #0x0
- ldrne r0, [r7, #0x2C]
- subne r6, r0, r4
- mvneq r6, #0x0
-_020D1B24:
- mov r0, r6
- add sp, sp, #0x4
- ldmia sp!, {r4-r7, lr}
- bx lr
-
- arm_func_start FSi_FindPath
-FSi_FindPath:
- stmdb sp!, {r4-r8,lr}
- sub sp, sp, #0x10
- mov r7, r1
- ldrb r1, [r7, #0x0]
- mov r8, r0
- mov r6, r2
- mov r5, r3
- cmp r1, #0x2f
- beq _020D1B60
- cmp r1, #0x5c
- bne _020D1B84
-_020D1B60:
- ldr r0, _020D1C90 ; =0x021D53EC
- mov r1, #0x0
- ldr r0, [r0, #0x0]
- strh r1, [sp, #0x4]
- str r0, [sp, #0x0]
- str r1, [sp, #0x8]
- strh r1, [sp, #0x6]
- add r7, r7, #0x1
- b _020D1C40
-_020D1B84:
- ldr r0, _020D1C90 ; =0x021D53EC
- add r3, sp, #0x0
- ldmia r0, {r0-r2}
- stmia r3, {r0-r2}
- mov r4, #0x0
-_020D1B98:
- ldrb r0, [r7, r4]
- cmp r0, #0x0
- beq _020D1C40
- cmp r0, #0x2f
- beq _020D1C40
- cmp r0, #0x5c
- beq _020D1C40
- cmp r0, #0x3a
- bne _020D1C34
- mov r0, r7
- mov r1, r4
- bl FS_FindArchive
-_020D1BC8:
- cmp r0, #0x0
- addeq sp, sp, #0x10
- moveq r0, #0x0
- ldmeqia sp!, {r4-r8,lr}
- bxeq lr
- ldr r1, [r0, #0x1C]
- ands r1, r1, #0x2
- movne r1, #0x1
- moveq r1, #0x0
- cmp r1, #0x0
- addeq sp, sp, #0x10
- moveq r0, #0x0
- ldmeqia sp!, {r4-r8,lr}
- bxeq lr
- mov r1, #0x0
- str r0, [sp]
- str r1, [sp, #0x8]
- strh r1, [sp, #0x6]
- strh r1, [sp, #0x4]
- add r0, r4, #0x1
- ldrb r0, [r7, r0]!
- cmp r0, #0x2f
- beq _020D1C2C
- cmp r0, #0x5c
- bne _020D1C40
-_020D1C2C:
- add r7, r7, #0x1
- b _020D1C40
-_020D1C34:
- add r4, r4, #0x1
- cmp r4, #0x3
- ble _020D1B98
-_020D1C40:
- ldr r1, [sp, #0x0]
- add r0, sp, #0x0
- str r1, [r8, #0x8]
- str r7, [r8, #0x3c]
- add r3, r8, #0x30
- ldmia r0, {r0-r2}
- stmia r3, {r0-r2}
- cmp r5, #0x0
- movne r0, #0x1
- strne r0, [r8, #0x40]
- strne r5, [r8, #0x44]
- moveq r0, #0x0
- streq r0, [r8, #0x40]
- mov r0, r8
- mov r1, #0x4
- streq r6, [r8, #0x44]
- bl FSi_SendCommand
- add sp, sp, #0x10
- ldmia sp!, {r4-r8,lr}
- bx lr
- .balign 4
-_020D1C90: .word 0x021D53EC
-
- arm_func_start FS_InitFile
-FS_InitFile:
- mov r3, #0x0
- str r3, [r0, #0x0]
- ldr r2, [r0, #0x0]
- mov r1, #0xe
- str r2, [r0, #0x4]
- str r3, [r0, #0x1c]
- ldr r2, [r0, #0x1c]
- str r2, [r0, #0x18]
- str r3, [r0, #0x8]
- str r1, [r0, #0x10]
- str r3, [r0, #0xc]
- bx lr
-
- arm_func_start FS_IsAvailable
-FS_IsAvailable: ; 0x020D1CC4
- ldr r0, _020D1CD0 ; =0x021D53F8
- ldr r0, [r0, #0x0]
- bx lr
- .balign 4
-_020D1CD0: .word 0x021D53F8
-
- arm_func_start FS_Init
-FS_Init: ; 0x020D1CD4
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r1, _020D1D0C ; =0x021D53F8
- ldr r2, [r1, #0x0]
- cmp r2, #0x0
- addne sp, sp, #0x4
- ldmneia sp!, {lr}
- bxne lr
- mov r2, #0x1
- str r2, [r1, #0x0]
- bl FSi_InitRom
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
- .balign 4
-_020D1D0C: .word 0x021D53F8
-
- arm_func_start FS_TryLoadTable
-FS_TryLoadTable: ; 0x020D1D10
- ldr ip, _020D1D28 ; =FUN_020D0D84
- mov r3, r0
- mov r2, r1
- ldr r0, _020D1D2C ; =0x021D5414
- mov r1, r3
- bx r12
- .balign 4
-_020D1D28: .word FUN_020D0D84
-_020D1D2C: .word 0x021D5414
-
- arm_func_start FS_SetDefaultDMA
-FS_SetDefaultDMA: ; 0x020D1D30
- stmdb sp!, {r4-r6,lr}
- mov r6, r0
- bl OS_DisableInterrupts
- mov r5, r0
- ldr r1, _020D1D7C ; =0x021D5400
- ldr r0, _020D1D80 ; =0x021D5414
- ldr r4, [r1, #0x0]
- bl FS_SuspendArchive
- ldr r1, _020D1D7C ; =0x021D5400
- cmp r0, #0x0
- str r6, [r1, #0x0]
- beq _020D1D68
- ldr r0, _020D1D80 ; =0x021D5414
- bl FS_ResumeArchive
-_020D1D68:
- mov r0, r5
- bl OS_RestoreInterrupts
- mov r0, r4
- ldmia sp!, {r4-r6,lr}
- bx lr
- .balign 4
-_020D1D7C: .word 0x021D5400
-_020D1D80: .word 0x021D5414
-
- arm_func_start FSi_InitRom
-FSi_InitRom: ; 0x020D1D84
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x14
- ldr r1, _020D1EE8 ; =0x021D5400
- str r0, [r1, #0x0]
- bl OS_GetLockID
- ldr r3, _020D1EEC ; =0x021D53FC
- ldr r2, _020D1EF0 ; =0x021D5404
- mov r12, #0x0
- ldr r1, _020D1EF4 ; =0x021D540C
- str r0, [r3, #0x0]
- str r12, [r2, #0x0]
- str r12, [r2, #0x4]
- str r12, [r1, #0x0]
- str r12, [r1, #0x4]
- bl CARD_Init
- ldr r0, _020D1EF8 ; =0x021D5414
- bl FS_InitArchive
- ldr r0, _020D1EF8 ; =0x021D5414
- ldr r1, _020D1EFC ; =0x02106830
- mov r2, #0x3
- bl FS_RegisterArchiveName
- ldr r0, _020D1F00 ; =0x027FFC40
- ldrh r0, [r0, #0x0]
- cmp r0, #0x2
- bne _020D1E4C
- ldr ip, _020D1EF0 ; =0x021D5404
- mvn r2, #0x0
- ldr r3, _020D1EF4 ; =0x021D540C
- mov lr, #0x0
- ldr r0, _020D1EF8 ; =0x021D5414
- ldr r1, _020D1F04 ; =FSi_EmptyArchiveProc
- str r2, [r12, #0x0]
- str lr, [r12, #0x4]
- str r2, [r3, #0x0]
- str lr, [r3, #0x4]
- bl FS_SetArchiveProc
- mov r1, #0x0
- str r1, [sp, #0x0]
- ldr r0, _020D1F08 ; =FSi_ReadDummyCallback
- str r1, [sp, #0x4]
- str r0, [sp, #0x8]
- ldr ip, _020D1F0C ; =FSi_WriteDummyCallback
- ldr r0, _020D1EF8 ; =0x021D5414
- mov r2, r1
- mov r3, r1
- str r12, [sp, #0xc]
- bl FS_LoadArchive
- add sp, sp, #0x14
- ldmia sp!, {r4-r5,lr}
- bx lr
-_020D1E4C:
- ldr r5, _020D1F10 ; =0x027FFE40
- ldr r0, _020D1EF8 ; =0x021D5414
- ldr r1, _020D1F14 ; =FSi_RomArchiveProc
- ldr r2, _020D1F18 ; =0x00000602
- ldr r4, _020D1F1C ; =0x027FFE48
- bl FS_SetArchiveProc
- ldr r1, [r5, #0x0]
- mvn r0, #0x0
- cmp r1, r0
- addeq sp, sp, #0x14
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- cmp r1, #0x0
- addeq sp, sp, #0x14
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- ldr r2, [r4, #0x0]
- cmp r2, r0
- addeq sp, sp, #0x14
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- cmp r2, #0x0
- addeq sp, sp, #0x14
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- str r1, [sp, #0x0]
- ldr r0, [r5, #0x4]
- ldr r1, _020D1F20 ; =FSi_ReadRomCallback
- str r0, [sp, #0x4]
- ldr r0, _020D1F0C ; =FSi_WriteDummyCallback
- str r1, [sp, #0x8]
- str r0, [sp, #0xc]
- ldr r3, [r4, #0x4]
- ldr r0, _020D1EF8 ; =0x021D5414
- mov r1, #0x0
- bl FS_LoadArchive
- add sp, sp, #0x14
- ldmia sp!, {r4-r5,lr}
- bx lr
- .balign 4
-_020D1EE8: .word 0x021D5400
-_020D1EEC: .word 0x021D53FC
-_020D1EF0: .word 0x021D5404
-_020D1EF4: .word 0x021D540C
-_020D1EF8: .word 0x021D5414
-_020D1EFC: .word 0x02106830
-_020D1F00: .word 0x027FFC40
-_020D1F04: .word FSi_EmptyArchiveProc
-_020D1F08: .word FSi_ReadDummyCallback
-_020D1F0C: .word FSi_WriteDummyCallback
-_020D1F10: .word 0x027FFE40
-_020D1F14: .word FSi_RomArchiveProc
-_020D1F18: .word 0x00000602
-_020D1F1C: .word 0x027FFE48
-_020D1F20: .word FSi_ReadRomCallback
-
- arm_func_start FSi_EmptyArchiveProc
-FSi_EmptyArchiveProc: ; 0x020D1F24
- mov r0, #0x4
- bx lr
-
- arm_func_start FSi_ReadDummyCallback
-FSi_ReadDummyCallback: ; 0x020D1F2C
- mov r0, #0x1
- bx lr
-
- arm_func_start FSi_RomArchiveProc
-FSi_RomArchiveProc: ; 0x020D1F34
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- cmp r1, #0x1
- beq _020D1FA0
- cmp r1, #0x9
- beq _020D1F58
- cmp r1, #0xa
- beq _020D1F7C
- b _020D1FB0
-_020D1F58:
- ldr r0, _020D1FC0 ; =0x021D53FC
- ldr r0, [r0, #0x0]
- mov r0, r0, lsl #0x10
- mov r0, r0, lsr #0x10
- bl CARD_LockRom
- add sp, sp, #0x4
- mov r0, #0x0
- ldmia sp!, {lr}
- bx lr
-_020D1F7C:
- ldr r0, _020D1FC0 ; =0x021D53FC
- ldr r0, [r0, #0x0]
- mov r0, r0, lsl #0x10
- mov r0, r0, lsr #0x10
- bl CARD_UnlockRom
- add sp, sp, #0x4
- mov r0, #0x0
- ldmia sp!, {lr}
- bx lr
-_020D1FA0:
- add sp, sp, #0x4
- mov r0, #0x4
- ldmia sp!, {lr}
- bx lr
-_020D1FB0:
- mov r0, #0x8
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
- .balign 4
-_020D1FC0: .word 0x021D53FC
-
- arm_func_start FSi_WriteDummyCallback
-FSi_WriteDummyCallback: ; 0x020D1FC4
- mov r0, #0x1
- bx lr
-
- arm_func_start FSi_ReadRomCallback
-FSi_ReadRomCallback: ; 0x020D1FCC
- stmdb sp!, {lr}
- sub sp, sp, #0xc
- ldr ip, _020D2010 ; =FSi_OnRomReadDone
- mov lr, r1
- str r12, [sp, #0x0]
- str r0, [sp, #0x4]
- mov r1, #0x1
- ldr r0, _020D2014 ; =0x021D5400
- str r1, [sp, #0x8]
- mov r1, r2
- ldr r0, [r0, #0x0]
- mov r2, lr
- bl CARDi_ReadRom
- mov r0, #0x6
- add sp, sp, #0xc
- ldmia sp!, {lr}
- bx lr
- .balign 4
-_020D2010: .word FSi_OnRomReadDone
-_020D2014: .word 0x021D5400
-
- arm_func_start FSi_OnRomReadDone
-FSi_OnRomReadDone: ; 0x020D2018
- stmdb sp!, {r4,lr}
- mov r4, r0
- bl CARD_IsPulledOut
-_020D2024:
- cmp r0, #0x0
- movne r1, #0x5
- moveq r1, #0x0
- mov r0, r4
- bl FS_NotifyArchiveAsyncEnd
- ldmia sp!, {r4,lr}
- bx lr
-
-
- arm_func_start FS_UnloadOverlay
-FS_UnloadOverlay: ; 0x020D2040
- stmdb sp!, {lr}
- sub sp, sp, #0x2c
- mov r3, r0
- mov r2, r1
- add r0, sp, #0x0
- mov r1, r3
- bl FS_LoadOverlayInfo
-_020D205C:
- cmp r0, #0x0
- beq _020D2074
- add r0, sp, #0x0
- bl FS_UnloadOverlayImage
- cmp r0, #0x0
- bne _020D2084
-_020D2074:
- add sp, sp, #0x2c
- mov r0, #0x0
- ldmfd sp!, {lr}
- bx lr
-_020D2084:
- mov r0, #0x1
- add sp, sp, #0x2c
- ldmfd sp!, {lr}
- bx lr
-
- arm_func_start FS_LoadOverlay
-FS_LoadOverlay: ; 0x020D2094
- stmdb sp!, {lr}
- sub sp, sp, #0x2c
- mov r3, r0
- mov r2, r1
- add r0, sp, #0x0
- mov r1, r3
- bl FS_LoadOverlayInfo
-_020D20B0:
- cmp r0, #0x0
- beq _020D20C8
- add r0, sp, #0x0
- bl FS_LoadOverlayImage
- cmp r0, #0x0
- bne _020D20D8
-_020D20C8:
- add sp, sp, #0x2c
- mov r0, #0x0
- ldmfd sp!, {lr}
- bx lr
-_020D20D8:
- add r0, sp, #0x0
- bl FS_StartOverlay
- mov r0, #0x1
- add sp, sp, #0x2c
- ldmfd sp!, {lr}
- bx lr
-
- arm_func_start FS_UnloadOverlayImage
-FS_UnloadOverlayImage: ; 0x020D20F0
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- bl FS_EndOverlay
- mov r0, #0x1
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start FS_EndOverlay
-FS_EndOverlay: ; 0x020D210C
- stmdb sp!, {r4-r11,lr}
- sub sp, sp, #0x4
- ldr r8, _020D220C ; =0x021D74C8
- mov r11, r0
- mov r9, #0x0
-_020D2120:
- ldr r1, [r11, #0x8]
- ldr r0, [r11, #0xc]
- ldr r5, [r11, #0x4]
- add r0, r1, r0
- mov r7, r9
- mov r6, r9
- add r4, r5, r0
- bl OS_DisableInterrupts
- ldr lr, [r8, #0x0]
- mov r10, r9
- mov r12, lr
- cmp lr, #0x0
- beq _020D21C4
-_020D2154:
- ldr r2, [r12, #0x8]
- ldr r3, [r12, #0x0]
- cmp r2, #0x0
- ldr r1, [r12, #0x4]
- bne _020D2178
- cmp r1, r5
- blo _020D2178
- cmp r1, r4
- blo _020D2188
-_020D2178:
- cmp r2, r5
- blo _020D21B4
- cmp r2, r4
- bhs _020D21B4
-_020D2188:
- cmp r6, #0x0
- strne r12, [r6, #0x0]
- moveq r7, r12
- cmp lr, r12
- streq r3, [r8, #0x0]
- moveq lr, r3
- str r9, [r12, #0x0]
- cmp r10, #0x0
- mov r6, r12
- strne r3, [r10, #0x0]
- b _020D21B8
-_020D21B4:
- mov r10, r12
-_020D21B8:
- mov r12, r3
- cmp r3, #0x0
- bne _020D2154
-_020D21C4:
- bl OS_RestoreInterrupts
-_020D21C8:
- cmp r7, #0x0
- addeq sp, sp, #0x4
- ldmeqia sp!, {r4-r11, lr}
- bxeq lr
-_020D21D8:
- ldr r1, [r7, #0x4]
- ldr r4, [r7]
- cmp r1, #0x0
- beq _020D21F0
- ldr r0, [r7, #0x8]
- blx r1
-_020D21F0:
- mov r7, r4
- cmp r4, #0x0
- bne _020D21D8
- b _020D2120
- add sp, sp, #0x4
- ldmia sp!, {r4-r11, lr}
- bx lr
-_020D220C: .word 0x021D74C8
-
- arm_func_start FS_StartOverlay
-FS_StartOverlay: ; 0x020D2210
- stmdb sp!, {r4-r6,lr}
- mov r5, r0
- bl FSi_GetOverlayBinarySize
- ldr r1, _020D2300 ; =0x027FFC40
- mov r4, r0
- ldrh r0, [r1, #0x0]
- cmp r0, #0x2
- bne _020D22A4
- ldrb r1, [r5, #0x1f]
- mov r0, #0x0
- ands r1, r1, #0x2
- beq _020D2280
- ldr r1, _020D2304 ; =0x02106F84
- ldr r3, _020D2308 ; =0x02106F84
- ldr r2, _020D230C ; =0x66666667
- sub r12, r1, r3
- smull r1, lr, r2, r12
- mov lr, lr, asr #0x3
- mov r1, r12, lsr #0x1f
- ldr r2, [r5, #0x0]
- add lr, r1, lr
- cmp r2, lr
- bhs _020D2280
- mov r0, #0x14
- mla r0, r2, r0, r3
- ldr r1, [r5, #0x4]
- mov r2, r4
- bl FSi_CompareDigest
-_020D2280:
- cmp r0, #0x0
- bne _020D22A4
- ldr r0, [r5, #0x4]
- mov r2, r4
- mov r1, #0x0
- bl MI_CpuFill8
- bl OS_Terminate
- ldmia sp!, {r4-r6,lr}
- bx lr
-_020D22A4:
- ldrb r0, [r5, #0x1f]
- ands r0, r0, #0x1
- beq _020D22BC
- ldr r0, [r5, #0x4]
- add r0, r0, r4
- bl MIi_UncompressBackward
-_020D22BC:
- ldr r0, [r5, #0x4]
- ldr r1, [r5, #0x8]
- bl DC_FlushRange
- ldr r6, [r5, #0x10]
- ldr r4, [r5, #0x14]
- cmp r6, r4
- ldmcsia sp!, {r4-r6,lr}
- bxcs lr
-_020D22DC:
- ldr r0, [r6, #0x0]
- cmp r0, #0x0
- beq _020D22EC
- blx r0
-_020D22EC:
- add r6, r6, #0x4
- cmp r6, r4
- blo _020D22DC
- ldmia sp!, {r4-r6,lr}
- bx lr
- .balign 4
-_020D2300: .word 0x027FFC40
-_020D2304: .word 0x02106F84
-_020D2308: .word 0x02106F84
-_020D230C: .word 0x66666667
-
- arm_func_start FSi_CompareDigest
-FSi_CompareDigest:
- stmdb sp!, {r4-r6,lr}
- sub sp, sp, #0x58
- mov r4, r0
- mov r6, r1
- mov r5, r2
- add r0, sp, #0x4
- mov r1, #0x0
- mov r2, #0x14
- bl MI_CpuFill8
- ldr r0, _020D23AC ; =0x02106834
- ldr r1, _020D23B0 ; =0x02106838
- ldr r0, [r0, #0x0]
- ldr r2, [r1, #0x0]
- add r1, sp, #0x18
- bl MI_CpuCopy8
- ldr r3, _020D23B0 ; =0x02106838
- mov r1, r6
- ldr r12, [r3, #0x0]
- mov r2, r5
- add r0, sp, #0x4
- add r3, sp, #0x18
- str r12, [sp, #0x0]
- bl MATH_CalcHMACSHA1
- add r2, sp, #0x4
- mov r3, #0x0
-_020D2374:
- ldr r1, [r2, #0x0]
- ldr r0, [r4, r3]
- cmp r1, r0
- bne _020D2394
- add r3, r3, #0x4
- cmp r3, #0x14
- add r2, r2, #0x4
- blo _020D2374
-_020D2394:
- cmp r3, #0x14
- moveq r0, #0x1
- movne r0, #0x0
- add sp, sp, #0x58
- ldmia sp!, {r4-r6,lr}
- bx lr
- .balign 4
-_020D23AC: .word 0x02106834
-_020D23B0: .word 0x02106838
-
- arm_func_start FS_LoadOverlayImage
-FS_LoadOverlayImage: ; 0x020D23B4
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x54
- mov r5, r0
- add r0, sp, #0x8
- bl FS_InitFile
-_020D23C8:
- add r0, sp, #0x0
- mov r1, r5
- bl FS_GetOverlayFileID
- add r1, sp, #0x0
- add r0, sp, #0x8
- ldmia r1, {r1, r2}
- bl FS_OpenFileFast
- cmp r0, #0x0
- addeq sp, sp, #0x54
- moveq r0, #0x0
- ldmeqia sp!, {r4-r5, lr}
- bxeq lr
- mov r0, r5
- bl FSi_GetOverlayBinarySize
- mov r4, r0
- mov r0, r5
- bl FS_ClearOverlayImage
- ldr r1, [r5, #0x4]
- add r0, sp, #0x8
- mov r2, r4
- bl FS_ReadFile
- cmp r4, r0
- beq _020D243C
- add r0, sp, #0x8
- bl FS_CloseFile
- add sp, sp, #0x54
- mov r0, #0x0
- ldmia sp!, {r4-r5, lr}
- bx lr
-_020D243C:
- add r0, sp, #0x8
- bl FS_CloseFile
- mov r0, #0x1
- add sp, sp, #0x54
- ldmia sp!, {r4-r5, lr}
- bx lr
-
- arm_func_start FS_LoadOverlayImageAsync
-FS_LoadOverlayImageAsync: ; 0x020D2454
- stmdb sp!, {r4-r6,lr}
- sub sp, sp, #0x8
- mov r5, r1
- mov r6, r0
- mov r0, r5
- bl FS_InitFile
-_020D246C:
- add r0, sp, #0x0
- mov r1, r6
- bl FS_GetOverlayFileID
- add r1, sp, #0x0
- mov r0, r5
- ldmia r1, {r1, r2}
- bl FS_OpenFileFast
- cmp r0, #0x0
- addeq sp, sp, #0x8
- moveq r0, #0x0
- ldmeqia sp!, {r4-r6, lr}
- bxeq lr
- mov r0, r6
- bl FSi_GetOverlayBinarySize
- mov r4, r0
- mov r0, r6
- bl FS_ClearOverlayImage
- ldr r1, [r6, #0x4]
- mov r0, r5
- mov r2, r4
- bl FS_ReadFileAsync
- cmp r4, r0
- addeq sp, sp, #0x8
- moveq r0, #0x1
- ldmeqia sp!, {r4-r6, lr}
- bxeq lr
- mov r0, r5
- bl FS_CloseFile
- mov r0, #0x0
- add sp, sp, #0x8
- ldmia sp!, {r4-r6, lr}
- bx lr
-
- arm_func_start FS_LoadOverlayInfo
-FS_LoadOverlayInfo:
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x64
- movs r4, r1
- mov r5, r0
- ldreq r0, _020D25EC ; =0x021D5404
- ldrne r0, _020D25F0 ; =0x021D540C
- ldr r3, [r0, #0x0]
- cmp r3, #0x0
- beq _020D25A8
- ldr r0, [r0, #0x4]
- mov r2, r2, lsl #0x5
- cmp r2, r0
- addcs sp, sp, #0x64
- movcs r0, #0x0
- ldmcsia sp!, {r4-r5,lr}
- bxcs lr
- add r0, r3, r2
- mov r1, r5
- mov r2, #0x20
- bl MI_CpuCopy8
- add r0, sp, #0x18
- str r4, [r5, #0x20]
- bl FS_InitFile
- add r0, sp, #0x10
- mov r1, r5
- bl FS_GetOverlayFileID
- add r1, sp, #0x10
- add r0, sp, #0x18
- ldmia r1, {r1-r2}
- bl FS_OpenFileFast
-_020D2564:
- cmp r0, #0x0
- addeq sp, sp, #0x64
- moveq r0, #0x0
- ldmeqia sp!, {r4-r5,lr}
- bxeq lr
- ldr r1, [sp, #0x3c]
- add r0, sp, #0x18
- str r1, [r5, #0x24]
- ldr r2, [sp, #0x40]
- ldr r1, [sp, #0x3c]
- sub r1, r2, r1
- str r1, [r5, #0x28]
- bl FS_CloseFile
- add sp, sp, #0x64
- mov r0, #0x1
- ldmia sp!, {r4-r5,lr}
- bx lr
-_020D25A8:
- ldr r1, _020D25F4 ; =0x027FFE50
- ldr ip, _020D25F8 ; =0x027FFE58
- ldr r0, [r1, #0x0]
- ldr r3, _020D25FC ; =0x021D5414
- str r0, [sp, #0x0]
- ldr r1, [r1, #0x4]
- mov r0, r5
- str r1, [sp, #0x4]
- ldr r5, [r12, #0x0]
- mov r1, r4
- str r5, [sp, #0x8]
- ldr r4, [r12, #0x4]
- str r4, [sp, #0xc]
- bl FSi_LoadOverlayInfoCore
- add sp, sp, #0x64
- ldmia sp!, {r4-r5,lr}
- bx lr
- .balign 4
-_020D25EC: .word 0x021D5404
-_020D25F0: .word 0x021D540C
-_020D25F4: .word 0x027FFE50
-_020D25F8: .word 0x027FFE58
-_020D25FC: .word 0x021D5414
-
- arm_func_start FSi_LoadOverlayInfoCore
-FSi_LoadOverlayInfoCore: ; 0x020D2600
- stmdb sp!, {r4-r9,lr}
- sub sp, sp, #0x54
- movs r9, r1
- ldreq r5, [sp, #0x74]
- ldreq r6, [sp, #0x70]
- ldrne r5, [sp, #0x7c]
- ldrne r6, [sp, #0x78]
- mov r7, r2, lsl #0x5
- cmp r7, r5
- mov r4, r0
- mov r8, r3
- addcs sp, sp, #0x54
- movcs r0, #0x0
- ldmcsia sp!, {r4-r9,lr}
- bxcs lr
- add r0, sp, #0xc
- bl FS_InitFile
- mvn r12, #0x0
- add r0, sp, #0xc
- mov r1, r8
- add r2, r6, r7
- add r3, r6, r5
- str r12, [sp, #0x0]
- bl FS_OpenFileDirect
-_020D2660:
- cmp r0, #0
- addeq sp, sp, #0x54
- moveq r0, #0
- ldmeqia sp!, {r4-r9, lr}
- bxeq lr
- add r0, sp, #12
- mov r1, r4
- mov r2, #32
- bl FS_ReadFile
- cmp r0, #32
- beq _020D26A4
- add r0, sp, #12
- bl FS_CloseFile
- add sp, sp, #0x54
- mov r0, #0x0
- ldmia sp!, {r4-r9, lr}
- bx lr
-_020D26A4:
- add r0, sp, #0xC
- bl FS_CloseFile
- add r0, sp, #0x4
- mov r1, r4
- str r9, [r4, #0x20]
- bl FS_GetOverlayFileID
- add r1, sp, #0x4
- add r0, sp, #0xC
- ldmia r1, {r1, r2}
- bl FS_OpenFileFast
- cmp r0, #0x0
- addeq sp, sp, #0x54
- moveq r0, #0x0
- ldmeqia sp!, {r4-r9, lr}
- bxeq lr
- ldr r1, [sp, #0x30]
- add r0, sp, #0xC
- str r1, [r4, #0x24]
- ldr r2, [sp, #0x34]
- ldr r1, [sp, #0x30]
- sub r1, r2, r1
- str r1, [r4, #0x28]
- bl FS_CloseFile
- mov r0, #0x1
- add sp, sp, #0x54
- ldmia sp!, {r4-r9, lr}
- bx lr
-
- arm_func_start FS_GetOverlayFileID
-FS_GetOverlayFileID: ; 0x020D2710
- sub sp, sp, #0x8
- ldr r2, _020D2734 ; =0x021D5414
- str r2, [sp, #0x0]
- ldr r1, [r1, #0x18]
- str r1, [sp, #0x4]
- str r2, [r0, #0x0]
- str r1, [r0, #0x4]
- add sp, sp, #0x8
- bx lr
- .balign 4
-_020D2734: .word 0x021D5414
-
- arm_func_start FS_ClearOverlayImage
-FS_ClearOverlayImage: ; 0x020D2738
- stmdb sp!, {r4-r6,lr}
- ldr r5, [r0, #0x8]
- ldr r1, [r0, #0xc]
- ldr r6, [r0, #0x4]
- add r4, r5, r1
- mov r0, r6
- mov r1, r4
- bl IC_InvalidateRange
- mov r0, r6
- mov r1, r4
- bl DC_InvalidateRange
- add r0, r6, r5
- sub r2, r4, r5
- mov r1, #0x0
- bl MI_CpuFill8
- ldmia sp!, {r4-r6,lr}
- bx lr
-
- arm_func_start FSi_GetOverlayBinarySize
-FSi_GetOverlayBinarySize: ; 0x020D277C
- ldrb r1, [r0, #0x1f]
- ands r1, r1, #0x1
- ldrne r0, [r0, #0x1c]
- movne r0, r0, lsl #0x8
- movne r0, r0, lsr #0x8
- ldreq r0, [r0, #0x8]
- bx lr
diff --git a/arm9/asm/libmwcc.s b/arm9/asm/libmwcc.s
index fcabec42..a6013179 100644
--- a/arm9/asm/libmwcc.s
+++ b/arm9/asm/libmwcc.s
@@ -3100,10 +3100,15 @@ __close_console: ; 0x020EC68C
mov r0, #0x0
bx lr
+ .section .rodata
+__static_initializers:
+ .word 0
+
+ .section .text
arm_func_start __call_static_initializers
__call_static_initializers: ; 0x020EC694
stmdb sp!, {r4,lr}
- ldr r4, _020EC6BC ; =0x02104774
+ ldr r4, _020EC6BC ; =__static_initializers
b _020EC6A8
_020EC6A0:
blx r0
@@ -3115,12 +3120,12 @@ _020EC6A8:
bne _020EC6A0
ldmia sp!, {r4,pc}
.balign 4
-_020EC6BC: .word 0x02104774
+_020EC6BC: .word __static_initializers
arm_func_start __destroy_global_chain
__destroy_global_chain: ; 0x020EC6C0
stmdb sp!, {r3-r5,lr}
- ldr r4, _020EC700 ; =0x021D74C8
+ ldr r4, _020EC700 ; =__global_destructor_chain
ldr r2, [r4, #0x0]
cmp r2, #0x0
ldmeqia sp!, {r3-r5,pc}
@@ -3138,7 +3143,7 @@ _020EC6D8:
bne _020EC6D8
ldmia sp!, {r3-r5,pc}
.balign 4
-_020EC700: .word 0x021D74C8
+_020EC700: .word __global_destructor_chain
arm_func_start _ExitProcess
_ExitProcess: ; 0x020EC704
diff --git a/arm9/asm/unk_020023C0.s b/arm9/asm/unk_020023C0.s
index ef8f06bf..0e8dfbdf 100644
--- a/arm9/asm/unk_020023C0.s
+++ b/arm9/asm/unk_020023C0.s
@@ -7792,551 +7792,3 @@ _02005F36:
mov r0, #0x0
bx lr
.balign 4
-
- ; Code that handles overlays?
-
- thumb_func_start FreeOverlayAllocation
-FreeOverlayAllocation: ; 0x02005F3C
- push {r4, lr}
- add r4, r0, #0x0
- ldr r0, [r4, #0x4]
- cmp r0, #0x1
- beq _02005F4A
- bl ErrorHandling
-_02005F4A:
- ldr r1, [r4, #0x0]
- mov r0, #0x0
- blx FS_UnloadOverlay
- cmp r0, #0x1
- beq _02005F5A
- bl ErrorHandling
-_02005F5A:
- mov r0, #0x0
- str r0, [r4, #0x4]
- pop {r4, pc}
-
- thumb_func_start UnloadOverlayByID
-UnloadOverlayByID: ; 0x02005F60
- push {r4, lr}
- add r4, r0, #0x0
- bl GetOverlayLoadDestination
- bl GetLoadedOverlaysInRegion
- mov r2, #0x0
- add r3, r0, #0x0
-_02005F70:
- ldr r1, [r3, #0x4]
- cmp r1, #0x1
- bne _02005F86
- ldr r1, [r3, #0x0]
- cmp r4, r1
- bne _02005F86
- lsl r1, r2, #0x3
- add r0, r0, r1
- bl FreeOverlayAllocation
- pop {r4, pc}
-_02005F86:
- add r2, r2, #0x1
- add r3, #0x8
- cmp r2, #0x8
- blt _02005F70
- pop {r4, pc}
-
- thumb_func_start GetOverlayLoadDestination
-GetOverlayLoadDestination: ; 0x02005F90
- push {lr}
- sub sp, #0x2c
- add r2, r0, #0x0
- add r0, sp, #0x0
- mov r1, #0x0
- blx FS_LoadOverlayInfo
- cmp r0, #0x1
- beq _02005FA6
- bl ErrorHandling
-_02005FA6:
- mov r0, #0x2
- ldr r2, [sp, #0x4]
- lsl r0, r0, #0x18
- cmp r2, r0
- bhi _02005FBC
- lsr r0, r0, #0x1
- cmp r2, r0
- blo _02005FBC
- add sp, #0x2c
- mov r0, #0x1
- pop {pc}
-_02005FBC:
- mov r0, #0x1
- ldr r1, _02005FD8 ; =0x027E0000
- lsl r0, r0, #0xe
- add r0, r1, r0
- cmp r2, r0
- bhi _02005FD2
- cmp r2, r1
- blo _02005FD2
- add sp, #0x2c
- mov r0, #0x2
- pop {pc}
-_02005FD2:
- mov r0, #0x0
- add sp, #0x2c
- pop {pc}
- .balign 4
-_02005FD8: .word 0x027E0000
-
- thumb_func_start HandleLoadOverlay
-HandleLoadOverlay: ; 0x02005FDC
- push {r3-r7, lr}
- add r4, r1, #0x0
- mov r1, #0x0
- mvn r1, r1
- add r5, r0, #0x0
- str r1, [sp, #0x0]
- bl CanOverlayBeLoaded
- cmp r0, #0x0
- bne _02005FF4
- mov r0, #0x0
- pop {r3-r7, pc}
-_02005FF4:
- add r0, r5, #0x0
- bl GetOverlayLoadDestination
- add r7, r0, #0x0
- bl GetLoadedOverlaysInRegion
- add r3, r0, #0x0
- mov r6, #0x0
- add r1, r3, #0x0
-_02006006:
- ldr r0, [r1, #0x4]
- cmp r0, #0x0
- bne _02006018
- lsl r1, r6, #0x3
- add r2, r3, r1
- mov r0, #0x1
- str r0, [r2, #0x4]
- str r5, [r3, r1]
- b _02006020
-_02006018:
- add r6, r6, #0x1
- add r1, #0x8
- cmp r6, #0x8
- blt _02006006
-_02006020:
- cmp r6, #0x8
- blt _0200602C
- bl ErrorHandling
- mov r0, #0x0
- pop {r3-r7, pc}
-_0200602C:
- sub r6, r7, #0x1
- cmp r6, #0x1
- bhi _0200603C
- mov r0, #0x0
- mvn r0, r0
- blx FS_SetDefaultDMA
- str r0, [sp, #0x0]
-_0200603C:
- cmp r4, #0x0
- beq _0200604A
- cmp r4, #0x1
- beq _02006056
- cmp r4, #0x2
- beq _02006062
- b _0200606E
-_0200604A:
- mov r0, #0x0
- add r1, r5, #0x0
- bl LoadOverlayNormal
- add r4, r0, #0x0
- b _02006076
-_02006056:
- mov r0, #0x0
- add r1, r5, #0x0
- bl LoadOverlayNoInit
- add r4, r0, #0x0
- b _02006076
-_02006062:
- mov r0, #0x0
- add r1, r5, #0x0
- bl LoadOverlayNoInitAsync
- add r4, r0, #0x0
- b _02006076
-_0200606E:
- bl ErrorHandling
- mov r0, #0x0
- pop {r3-r7, pc}
-_02006076:
- cmp r6, #0x1
- bhi _02006080
- ldr r0, [sp, #0x0]
- blx FS_SetDefaultDMA
-_02006080:
- cmp r4, #0x0
- bne _0200608C
- bl ErrorHandling
- mov r0, #0x0
- pop {r3-r7, pc}
-_0200608C:
- mov r0, #0x1
- pop {r3-r7, pc}
-
- thumb_func_start CanOverlayBeLoaded
-CanOverlayBeLoaded: ; 0x02006090
- push {r3-r7, lr}
- sub sp, #0x10
- add r1, sp, #0xc
- add r2, sp, #0x8
- add r4, r0, #0x0
- bl GetOverlayRamBounds
- cmp r0, #0x0
- bne _020060A8
- add sp, #0x10
- mov r0, #0x0
- pop {r3-r7, pc}
-_020060A8:
- add r0, r4, #0x0
- bl GetOverlayLoadDestination
- bl GetLoadedOverlaysInRegion
- add r5, r0, #0x0
- mov r4, #0x0
- add r6, sp, #0x4
- add r7, sp, #0x0
-_020060BA:
- ldr r0, [r5, #0x4]
- cmp r0, #0x1
- bne _020060FC
- ldr r0, [r5, #0x0]
- add r1, r6, #0x0
- add r2, r7, #0x0
- bl GetOverlayRamBounds
- cmp r0, #0x1
- bne _020060FC
- ldr r1, [sp, #0x4]
- ldr r2, [sp, #0xc]
- cmp r2, r1
- blo _020060DC
- ldr r0, [sp, #0x0]
- cmp r2, r0
- blo _020060F2
-_020060DC:
- ldr r3, [sp, #0x8]
- cmp r3, r1
- bls _020060E8
- ldr r0, [sp, #0x0]
- cmp r3, r0
- bls _020060F2
-_020060E8:
- cmp r2, r1
- bhi _020060FC
- ldr r0, [sp, #0x0]
- cmp r3, r0
- blo _020060FC
-_020060F2:
- bl ErrorHandling
- add sp, #0x10
- mov r0, #0x0
- pop {r3-r7, pc}
-_020060FC:
- add r4, r4, #0x1
- add r5, #0x8
- cmp r4, #0x8
- blt _020060BA
- mov r0, #0x1
- add sp, #0x10
- pop {r3-r7, pc}
- .balign 4
-
- thumb_func_start GetLoadedOverlaysInRegion
-GetLoadedOverlaysInRegion: ; 0x0200610C
- cmp r0, #0x0
- beq _02006118
- cmp r0, #0x1
- beq _0200611C
- cmp r0, #0x2
- beq _02006120
-_02006118:
- ldr r0, _02006124 ; =0x021C45B0
- bx lr
-_0200611C:
- ldr r0, _02006128 ; =0x021C45F0
- bx lr
-_02006120:
- ldr r0, _0200612C ; =0x021C4630
- bx lr
- .balign 4
-_02006124: .word 0x021C45B0
-_02006128: .word 0x021C45F0
-_0200612C: .word 0x021C4630
-
- thumb_func_start GetOverlayRamBounds
-GetOverlayRamBounds: ; 0x02006130
- push {r4-r5, lr}
- sub sp, #0x2c
- add r3, r0, #0x0
- add r5, r1, #0x0
- add r4, r2, #0x0
- add r0, sp, #0x0
- mov r1, #0x0
- add r2, r3, #0x0
- blx FS_LoadOverlayInfo
- cmp r0, #0x0
- bne _02006152
- bl ErrorHandling
- add sp, #0x2c
- mov r0, #0x0
- pop {r4-r5, pc}
-_02006152:
- ldr r2, [sp, #0x4]
- str r2, [r5, #0x0]
- ldr r1, [sp, #0x8]
- ldr r0, [sp, #0xc]
- add r0, r1, r0
- add r0, r2, r0
- str r0, [r4, #0x0]
- mov r0, #0x1
- add sp, #0x2c
- pop {r4-r5, pc}
- .balign 4
-
- thumb_func_start LoadOverlayNormal
-LoadOverlayNormal: ; 0x02006168
- ldr r3, _0200616C ; =FS_LoadOverlay
- bx r3
- .balign 4
-_0200616C: .word FS_LoadOverlay
-
- thumb_func_start LoadOverlayNoInit
-LoadOverlayNoInit: ; 0x02006170
- push {lr}
- sub sp, #0x2c
- add r3, r0, #0x0
- add r2, r1, #0x0
- add r0, sp, #0x0
- add r1, r3, #0x0
- blx FS_LoadOverlayInfo
- cmp r0, #0x0
- bne _0200618A
- add sp, #0x2c
- mov r0, #0x0
- pop {pc}
-_0200618A:
- add r0, sp, #0x0
- blx FS_LoadOverlayImage
- cmp r0, #0x0
- bne _0200619A
- add sp, #0x2c
- mov r0, #0x0
- pop {pc}
-_0200619A:
- add r0, sp, #0x0
- blx FS_StartOverlay
- mov r0, #0x1
- add sp, #0x2c
- pop {pc}
- .balign 4
-
- thumb_func_start LoadOverlayNoInitAsync
-LoadOverlayNoInitAsync: ; 0x020061A8
- push {lr}
- sub sp, #0x74
- add r3, r0, #0x0
- add r2, r1, #0x0
- add r0, sp, #0x0
- add r1, r3, #0x0
- blx FS_LoadOverlayInfo
- cmp r0, #0x0
- bne _020061C2
- add sp, #0x74
- mov r0, #0x0
- pop {pc}
-_020061C2:
- add r0, sp, #0x2c
- blx FS_InitFile
- add r0, sp, #0x0
- add r1, sp, #0x2c
- blx FS_LoadOverlayImageAsync
- add r0, sp, #0x2c
- blx FS_WaitAsync
- add r0, sp, #0x2c
- blx FS_CloseFile
- add r0, sp, #0x0
- blx FS_StartOverlay
- mov r0, #0x1
- add sp, #0x74
- pop {pc}
-
- thumb_func_start FUN_020061E8
-FUN_020061E8: ; 0x020061E8
- push {r3-r7, lr}
- add r5, r1, #0x0
- add r6, r0, #0x0
- add r7, r2, #0x0
- cmp r5, #0x0
- beq _0200620C
- add r0, r3, #0x0
- bl FUN_02016998
- add r4, r0, #0x0
- bne _02006202
- mov r0, #0x0
- pop {r3-r7, pc}
-_02006202:
- mov r1, #0x0
- add r2, r5, #0x0
- blx Call_FillMemWithValue
- b _0200620E
-_0200620C:
- mov r4, #0x0
-_0200620E:
- add r0, r6, #0x0
- add r1, r4, #0x0
- add r2, r7, #0x0
- bl FUN_0200CA44
- pop {r3-r7, pc}
- .balign 4
-
- thumb_func_start FUN_0200621C
-FUN_0200621C: ; 0x0200621C
- push {r4, lr}
- add r4, r0, #0x0
- bl FUN_0201B6C8
- cmp r0, #0x0
- beq _0200622C
- bl FUN_02016A18
-_0200622C:
- add r0, r4, #0x0
- bl FUN_0200CAB4
- pop {r4, pc}
-
- thumb_func_start FUN_02006234
-FUN_02006234: ; 0x02006234
- push {r3-r5, lr}
- add r5, r0, #0x0
- add r4, r1, #0x0
- add r0, r2, #0x0
- mov r1, #0x28
- bl FUN_02016998
- add r3, r0, #0x0
- add r2, r3, #0x0
- ldmia r5!, {r0-r1}
- stmia r2!, {r0-r1}
- ldmia r5!, {r0-r1}
- stmia r2!, {r0-r1}
- mov r0, #0x0
- str r0, [r3, #0x10]
- str r0, [r3, #0x14]
- str r4, [r3, #0x18]
- str r0, [r3, #0x1c]
- str r0, [r3, #0x20]
- str r0, [r3, #0x24]
- add r0, r3, #0x0
- pop {r3-r5, pc}
-
- thumb_func_start FUN_02006260
-FUN_02006260: ; 0x02006260
- ldr r3, _02006264 ; =FUN_02016A18
- bx r3
- .balign 4
-_02006264: .word FUN_02016A18
-
- thumb_func_start FUN_02006268
-FUN_02006268: ; 0x02006268
- push {r4, lr}
- add r4, r0, #0x0
- add r0, r2, #0x0
- bl FUN_02016998
- str r0, [r4, #0x1c]
- pop {r4, pc}
- .balign 4
-
- thumb_func_start FUN_02006278
-FUN_02006278: ; 0x02006278
- ldr r0, [r0, #0x1c]
- bx lr
-
- thumb_func_start FUN_0200627C
-FUN_0200627C: ; 0x0200627C
- push {r4, lr}
- add r4, r0, #0x0
- ldr r0, [r4, #0x1c]
- bl FUN_02016A18
- mov r0, #0x0
- str r0, [r4, #0x1c]
- pop {r4, pc}
-
- thumb_func_start FUN_0200628C
-FUN_0200628C: ; 0x0200628C
- ldr r0, [r0, #0x18]
- bx lr
-
- thumb_func_start FUN_02006290
-FUN_02006290: ; 0x02006290
- push {r4, lr}
- add r4, r0, #0x0
- ldr r1, [r4, #0x10]
- cmp r1, #0x3
- bhi _0200630E
- add r1, r1, r1
- add r1, pc
- ldrh r1, [r1, #0x6]
- lsl r1, r1, #0x10
- asr r1, r1, #0x10
- add pc, r1
-_020062A6: ; jump table (using 16-bit offset)
- .short _020062AE - _020062A6 - 2; case 0
- .short _020062C2 - _020062A6 - 2; case 1
- .short _020062DA - _020062A6 - 2; case 2
- .short _020062F0 - _020062A6 - 2; case 3
-_020062AE:
- mov r1, #0x0
- ldr r0, [r4, #0xc]
- mvn r1, r1
- cmp r0, r1
- beq _020062BE
- mov r1, #0x2
- bl HandleLoadOverlay
-_020062BE:
- mov r0, #0x1
- str r0, [r4, #0x10]
-_020062C2:
- add r1, r4, #0x0
- ldr r2, [r4, #0x0]
- add r0, r4, #0x0
- add r1, #0x14
- blx r2
- cmp r0, #0x1
- bne _0200630E
- mov r0, #0x2
- str r0, [r4, #0x10]
- mov r0, #0x0
- str r0, [r4, #0x14]
- b _0200630E
-_020062DA:
- add r1, r4, #0x0
- ldr r2, [r4, #0x4]
- add r1, #0x14
- blx r2
- cmp r0, #0x1
- bne _0200630E
- mov r0, #0x3
- str r0, [r4, #0x10]
- mov r0, #0x0
- str r0, [r4, #0x14]
- b _0200630E
-_020062F0:
- add r1, r4, #0x0
- ldr r2, [r4, #0x8]
- add r1, #0x14
- blx r2
- cmp r0, #0x1
- bne _0200630E
- mov r1, #0x0
- ldr r0, [r4, #0xc]
- mvn r1, r1
- cmp r0, r1
- beq _0200630A
- bl UnloadOverlayByID
-_0200630A:
- mov r0, #0x1
- pop {r4, pc}
-_0200630E:
- mov r0, #0x0
- pop {r4, pc}
- .balign 4
diff --git a/arm9/asm/unk_020061E8.s b/arm9/asm/unk_020061E8.s
new file mode 100644
index 00000000..3b8df8d6
--- /dev/null
+++ b/arm9/asm/unk_020061E8.s
@@ -0,0 +1,181 @@
+ .include "asm/macros.inc"
+ .include "global.inc"
+ .section .text
+
+ thumb_func_start FUN_020061E8
+FUN_020061E8: ; 0x020061E8
+ push {r3-r7, lr}
+ add r5, r1, #0x0
+ add r6, r0, #0x0
+ add r7, r2, #0x0
+ cmp r5, #0x0
+ beq _0200620C
+ add r0, r3, #0x0
+ bl FUN_02016998
+ add r4, r0, #0x0
+ bne _02006202
+ mov r0, #0x0
+ pop {r3-r7, pc}
+_02006202:
+ mov r1, #0x0
+ add r2, r5, #0x0
+ blx Call_FillMemWithValue
+ b _0200620E
+_0200620C:
+ mov r4, #0x0
+_0200620E:
+ add r0, r6, #0x0
+ add r1, r4, #0x0
+ add r2, r7, #0x0
+ bl FUN_0200CA44
+ pop {r3-r7, pc}
+ .balign 4
+
+ thumb_func_start FUN_0200621C
+FUN_0200621C: ; 0x0200621C
+ push {r4, lr}
+ add r4, r0, #0x0
+ bl FUN_0201B6C8
+ cmp r0, #0x0
+ beq _0200622C
+ bl FUN_02016A18
+_0200622C:
+ add r0, r4, #0x0
+ bl FUN_0200CAB4
+ pop {r4, pc}
+
+ thumb_func_start FUN_02006234
+FUN_02006234: ; 0x02006234
+ push {r3-r5, lr}
+ add r5, r0, #0x0
+ add r4, r1, #0x0
+ add r0, r2, #0x0
+ mov r1, #0x28
+ bl FUN_02016998
+ add r3, r0, #0x0
+ add r2, r3, #0x0
+ ldmia r5!, {r0-r1}
+ stmia r2!, {r0-r1}
+ ldmia r5!, {r0-r1}
+ stmia r2!, {r0-r1}
+ mov r0, #0x0
+ str r0, [r3, #0x10]
+ str r0, [r3, #0x14]
+ str r4, [r3, #0x18]
+ str r0, [r3, #0x1c]
+ str r0, [r3, #0x20]
+ str r0, [r3, #0x24]
+ add r0, r3, #0x0
+ pop {r3-r5, pc}
+
+ thumb_func_start FUN_02006260
+FUN_02006260: ; 0x02006260
+ ldr r3, _02006264 ; =FUN_02016A18
+ bx r3
+ .balign 4
+_02006264: .word FUN_02016A18
+
+ thumb_func_start FUN_02006268
+FUN_02006268: ; 0x02006268
+ push {r4, lr}
+ add r4, r0, #0x0
+ add r0, r2, #0x0
+ bl FUN_02016998
+ str r0, [r4, #0x1c]
+ pop {r4, pc}
+ .balign 4
+
+ thumb_func_start FUN_02006278
+FUN_02006278: ; 0x02006278
+ ldr r0, [r0, #0x1c]
+ bx lr
+
+ thumb_func_start FUN_0200627C
+FUN_0200627C: ; 0x0200627C
+ push {r4, lr}
+ add r4, r0, #0x0
+ ldr r0, [r4, #0x1c]
+ bl FUN_02016A18
+ mov r0, #0x0
+ str r0, [r4, #0x1c]
+ pop {r4, pc}
+
+ thumb_func_start FUN_0200628C
+FUN_0200628C: ; 0x0200628C
+ ldr r0, [r0, #0x18]
+ bx lr
+
+ thumb_func_start FUN_02006290
+FUN_02006290: ; 0x02006290
+ push {r4, lr}
+ add r4, r0, #0x0
+ ldr r1, [r4, #0x10]
+ cmp r1, #0x3
+ bhi _0200630E
+ add r1, r1, r1
+ add r1, pc
+ ldrh r1, [r1, #0x6]
+ lsl r1, r1, #0x10
+ asr r1, r1, #0x10
+ add pc, r1
+_020062A6: ; jump table (using 16-bit offset)
+ .short _020062AE - _020062A6 - 2; case 0
+ .short _020062C2 - _020062A6 - 2; case 1
+ .short _020062DA - _020062A6 - 2; case 2
+ .short _020062F0 - _020062A6 - 2; case 3
+_020062AE:
+ mov r1, #0x0
+ ldr r0, [r4, #0xc]
+ mvn r1, r1
+ cmp r0, r1
+ beq _020062BE
+ mov r1, #0x2
+ bl HandleLoadOverlay
+_020062BE:
+ mov r0, #0x1
+ str r0, [r4, #0x10]
+_020062C2:
+ add r1, r4, #0x0
+ ldr r2, [r4, #0x0]
+ add r0, r4, #0x0
+ add r1, #0x14
+ blx r2
+ cmp r0, #0x1
+ bne _0200630E
+ mov r0, #0x2
+ str r0, [r4, #0x10]
+ mov r0, #0x0
+ str r0, [r4, #0x14]
+ b _0200630E
+_020062DA:
+ add r1, r4, #0x0
+ ldr r2, [r4, #0x4]
+ add r1, #0x14
+ blx r2
+ cmp r0, #0x1
+ bne _0200630E
+ mov r0, #0x3
+ str r0, [r4, #0x10]
+ mov r0, #0x0
+ str r0, [r4, #0x14]
+ b _0200630E
+_020062F0:
+ add r1, r4, #0x0
+ ldr r2, [r4, #0x8]
+ add r1, #0x14
+ blx r2
+ cmp r0, #0x1
+ bne _0200630E
+ mov r1, #0x0
+ ldr r0, [r4, #0xc]
+ mvn r1, r1
+ cmp r0, r1
+ beq _0200630A
+ bl UnloadOverlayByID
+_0200630A:
+ mov r0, #0x1
+ pop {r4, pc}
+_0200630E:
+ mov r0, #0x0
+ pop {r4, pc}
+ .balign 4
diff --git a/arm9/asm/unk_02006864.s b/arm9/asm/unk_02006864.s
index ae663521..bcbdc275 100644
--- a/arm9/asm/unk_02006864.s
+++ b/arm9/asm/unk_02006864.s
@@ -98220,7 +98220,7 @@ FUN_0203341C: ; 0x0203341C
mov r1, #0x31
ldr r0, [r0, #0x0]
ldr r0, [r0, #0x28]
- bl FUN_021D74E0
+ bl MOD05_021D74E0
ldr r0, _02033464 ; =FUN_020335D0
bl FUN_021D83A8
bl FUN_0202FA10
diff --git a/arm9/asm/unk_020910EC.s b/arm9/asm/unk_020910EC.s
index 3ae14dd4..2108f3de 100644
--- a/arm9/asm/unk_020910EC.s
+++ b/arm9/asm/unk_020910EC.s
@@ -3,6 +3,8 @@
.text
+ ; Nintendo DWC
+
arm_func_start FUN_020910EC
FUN_020910EC: ; 0x020910EC
stmdb sp!, {r4-r5,lr}
@@ -6591,11 +6593,13 @@ _02096B08: .word 0x0000FFFF
_02096B0C: .word 0x020FF580
_02096B10: .word 0x020FF578
+ .extern _SDK_NintendoDWC
+
arm_func_start FUN_02096B14
FUN_02096B14: ; 0x02096B14
stmdb sp!, {r4-r6,lr}
mov r6, r0
- ldr r0, _02096B74 ; =0x02000B8C
+ ldr r0, _02096B74 ; =_SDK_NintendoDWC
mov r4, #0x0
bl OSi_ReferSymbol
mov r0, r6
@@ -6621,7 +6625,9 @@ _02096B64:
moveq r0, #0x0
ldmia sp!, {r4-r6,pc}
.balign 4
-_02096B74: .word 0x02000B8C
+_02096B74: .word _SDK_NintendoDWC
+
+ ; Nintendo Wifi (?)
arm_func_start FUN_02096B78
FUN_02096B78: ; 0x02096B78
@@ -7657,11 +7663,13 @@ _02097828: .word 0x021C8CC0
_0209782C: .word 0x021061F4
_02097830: .word 0x021C8CD0
+ .extern _SDK_NintendoWiFi
+
arm_func_start FUN_02097834
FUN_02097834: ; 0x02097834
stmdb sp!, {r4,lr}
mov r4, r0
- ldr r0, _02097870 ; =0x02000BC4
+ ldr r0, _02097870 ; =_SDK_NintendoWiFi
bl OSi_ReferSymbol
ldr r0, _02097874 ; =0x021C8CC0
ldr r1, [r0, #0x0]
@@ -7675,9 +7683,11 @@ FUN_02097834: ; 0x02097834
ldmia sp!, {r4,lr}
bx lr
.balign 4
-_02097870: .word 0x02000BC4
+_02097870: .word _SDK_NintendoWiFi
_02097874: .word 0x021C8CC0
+ ; Ubiquitous CPS (?)
+
arm_func_start FUN_02097878
FUN_02097878: ; 0x02097878
stmdb sp!, {r4-r9,lr}
@@ -17528,12 +17538,14 @@ _0209FD74:
_0209FD8C: .word 0x021C90A0
_0209FD90: .word 0x021C8EF8
+ .extern _SDK_UbiquitousCPS
+
arm_func_start FUN_0209FD94
FUN_0209FD94: ; 0x0209FD94
stmdb sp!, {r4-r6,lr}
sub sp, sp, #0x8
mov r4, r0
- ldr r0, _0209FFD4 ; =0x02000BEC
+ ldr r0, _0209FFD4 ; =_SDK_UbiquitousCPS
bl OSi_ReferSymbol
ldr r12, [r4, #0x14]
ldr r6, [r4, #0x18]
@@ -17679,7 +17691,7 @@ _0209FE60:
ldmia sp!, {r4-r6,lr}
bx lr
.balign 4
-_0209FFD4: .word 0x02000BEC
+_0209FFD4: .word _SDK_UbiquitousCPS
_0209FFD8: .word 0x021C8F24
_0209FFDC: .word 0x6C078965
_0209FFE0: .word 0x5D588B65
@@ -17711,6 +17723,8 @@ _020A0044: .word 0x021C90A0
_020A0048: .word FUN_0209BA80
_020A004C: .word 0x021C9EE0
+ ; Ubiquitous SSL (?)
+
arm_func_start FUN_020A0050
FUN_020A0050: ; 0x020A0050
mov r0, #0x1
@@ -17911,11 +17925,13 @@ _020A02E0: .word 0x021CA6FC
_020A02E4: .word 0x000003BD
_020A02E8: .word 0x021D3498
+ .extern _SDK_UbiquitousSSL
+
arm_func_start FUN_020A02EC
FUN_020A02EC:
stmdb sp!, {r4,lr}
mov r4, r0
- ldr r0, _020A0318 ; =0x02000C04
+ ldr r0, _020A0318 ; =_SDK_UbiquitousSSL
bl OSi_ReferSymbol
ldr r0, _020A031C ; =0x021D3498
ldr r0, [r0, #0x4]
@@ -17925,9 +17941,11 @@ FUN_020A02EC:
ldmia sp!, {r4,lr}
bx lr
.balign 4
-_020A0318: .word 0x02000C04
+_020A0318: .word _SDK_UbiquitousSSL
_020A031C: .word 0x021D3498
+ ; Abiosso libVCT (?)
+
arm_func_start FUN_020A0320
FUN_020A0320: ; 0x020A0320
stmdb sp!, {r4,lr}
@@ -33682,23 +33700,22 @@ FUN_020AD904: ; 0x020AD904
_020AD934: .word 0x021CCD20
_020AD938: .word 0x021CCD1C
+ .extern _SDK_AbiossolibVCT
+
arm_func_start FUN_020AD93C
FUN_020AD93C: ; 0x020AD93C
stmdb sp!, {r4,lr}
mov r4, r0
- ldr r0, _020ADA78 ; =0x02000C1C
+ ldr r0, _020ADA78 ; =_SDK_AbiossolibVCT
bl OSi_ReferSymbol
-_020AD94C: ; 0x020AD94C
cmp r4, #0x0
moveq r0, #0x0
ldmeqia sp!, {r4,pc}
-_020AD958: ; 0x020AD958
ldr r0, _020ADA7C ; =0x021CCD1C
ldr r0, [r0, #0x0]
cmp r0, #0x0
movne r0, #0x1
ldmneia sp!, {r4,pc}
-_020AD96C: ; 0x020AD96C
ldr r0, [r4, #0x8]
cmp r0, #0x1
beq _020AD98C
@@ -33712,7 +33729,6 @@ _020AD98C:
cmp r0, #0x0
moveq r0, #0x0
ldmeqia sp!, {r4,pc}
-_020AD99C: ; 0x020AD99C
ldr r2, [r4, #0x10]
cmp r2, #0x0
beq _020AD9B4
@@ -33728,7 +33744,6 @@ _020AD9BC:
adds r0, r1, r0, ror #0x1b
movne r0, #0x0
ldmneia sp!, {r4,pc}
-_020AD9D0: ; 0x020AD9D0
ldr r0, _020ADA80 ; =0x021CCD20
mov r1, #0x0
mov r2, #0x18
@@ -33745,47 +33760,41 @@ _020AD9D0: ; 0x020AD9D0
ldrb r2, [r4, #0xc]
cmp r2, #0x20
ldmcsia sp!, {r4,pc}
-_020ADA10: ; 0x020ADA10
strb r2, [r1, #0x0]
ldr r0, [r4, #0x10]
ldr r1, [r4, #0x14]
bl FUN_020ACE30
-_020ADA20: ; 0x020ADA20
cmp r0, #0x0
bne _020ADA34
bl FUN_020ACE10
-_020ADA2C: ; 0x020ADA2C
mov r0, #0x0
ldmia sp!, {r4,pc}
_020ADA34:
mov r0, r4
bl FUN_020AC97C
-_020ADA3C: ; 0x020ADA3C
cmp r0, #0x0
bne _020ADA50
bl FUN_020ACE10
-_020ADA48: ; 0x020ADA48
mov r0, #0x0
ldmia sp!, {r4,pc}
_020ADA50:
bl FUN_020AAF58
-_020ADA54: ; 0x020ADA54
cmp r0, #0x0
ldrne r1, _020ADA7C ; =0x021CCD1C
movne r0, #0x1
strne r0, [r1, #0x0]
ldmneia sp!, {r4,pc}
-_020ADA68: ; 0x020ADA68
bl FUN_020AC964
bl FUN_020ACE10
-_020ADA70: ; 0x020ADA70
mov r0, #0x0
ldmia sp!, {r4,pc}
.balign 4
-_020ADA78: .word 0x02000C1C
+_020ADA78: .word _SDK_AbiossolibVCT
_020ADA7C: .word 0x021CCD1C
_020ADA80: .word 0x021CCD20
+ ; unknown
+
arm_func_start FUN_020ADA84
FUN_020ADA84: ; 0x020ADA84
cmp r1, #0x0
diff --git a/arm9/data/rom2.s b/arm9/data/rom2.s
index 0f18b45a..9650cc4c 100644
--- a/arm9/data/rom2.s
+++ b/arm9/data/rom2.s
@@ -2,6 +2,6 @@
.include "asm/macros.inc"
.include "global.inc"
- .data
+ .section .rodata
.incbin "baserom.nds", 0xF0710, 0x3F8 ; this does not seem to be code
diff --git a/arm9/data/rom2_2.s b/arm9/data/rom2_2.s
index d5055773..c5624b8e 100644
--- a/arm9/data/rom2_2.s
+++ b/arm9/data/rom2_2.s
@@ -3,7 +3,7 @@
/* rom2.s TODO: Disassemble */
-.section .data
+.section .rodata
.incbin "baserom.nds", 0xF0B50, 0x6A0C
@@ -731,4 +731,4 @@ gScriptCmdTable: ; 0x020F355C
.word FUN_0203AF84
.word FUN_0203AFA4
-.incbin "baserom.nds", 0xF80A0, 0x12F00
+ .incbin "baserom.nds", 0xF80A0, 0xFEE0
diff --git a/arm9/data/rom2_3.s b/arm9/data/rom2_3.s
new file mode 100644
index 00000000..14ce7502
--- /dev/null
+++ b/arm9/data/rom2_3.s
@@ -0,0 +1,12 @@
+ .include "asm/macros.inc"
+ .include "global.inc"
+
+ /* rom2.s TODO: Disassemble */
+
+ .section .rodata
+
+ /* 0x02103FE4 */
+ .incbin "baserom.nds", 0x107FE4, 0x790
+
+ .section .data
+ .incbin "baserom.nds", 0x108780, 0x20ac
diff --git a/arm9/data/rom2_4.s b/arm9/data/rom2_4.s
new file mode 100644
index 00000000..c543924a
--- /dev/null
+++ b/arm9/data/rom2_4.s
@@ -0,0 +1,9 @@
+ .include "asm/macros.inc"
+ .include "global.inc"
+
+ /* rom2.s TODO: Disassemble */
+
+ .section .data
+
+ /* 0x0210683C */
+ .incbin "baserom.nds", 0x10a83C, 0x764
diff --git a/arm9/global.inc b/arm9/global.inc
index dfebf783..508f71de 100644
--- a/arm9/global.inc
+++ b/arm9/global.inc
@@ -2654,7 +2654,7 @@
.extern FUN_020C39CC
.extern FUN_020C6034
.extern FUN_020C605C
-.extern FUN_021D74E0
+.extern MOD05_021D74E0
.extern FUN_021D7660
.extern FUN_021D76AC
.extern FUN_021D77C4
@@ -3315,7 +3315,7 @@
.extern MATH_CalcCRC16CCITT
.extern MATH_CalcCRC32
.extern MATH_CalcCRC8
-.extern MATH_CalcHMACSHA1
+.extern DGT_Hash2CalcHmac
.extern MATH_CalcMD5
.extern MATH_CalcSHA1
.extern MATH_CountPopulation
@@ -3806,6 +3806,7 @@
.extern sys_writec
.extern tempName_NNS_FndAllocFromExpHeapEx
.extern tempName_NNS_FndCreateExpHeapEx
+.extern __global_destructor_chain
.extern thunk_FUN_02096e4c
.extern thunk_FUN_02097190
.extern thunk_FUN_020995dc
@@ -5021,9 +5022,9 @@
.extern FUN_020B7218
.extern FUN_020C2444
.extern FUN_020C5E04
-.extern FUN_020D0D84
-.extern FUN_020D0EB0
-.extern FUN_020D0FF0
+.extern FS_LoadArchiveTables
+.extern FS_UnloadArchive
+.extern FS_ReleaseArchiveName
.extern FUN_021EB9A4
.extern FUN_021EB9D8
.extern FUN_021EBAE8
@@ -5111,6 +5112,15 @@
.extern MOD11_02249E58
.extern MOD11_0224B310
.extern MOD11_0224C12C
+.extern FSi_ExecuteSyncCommand
+.extern FSi_InitRom
+.extern FSi_SendCommand
+.extern FSi_TranslateCommand
+.extern FS_NotifyArchiveAsyncEnd
+.extern FS_ResumeArchive
+.extern FS_SuspendArchive
+.extern FS_ReadFileAsync
+.extern FSi_ReleaseCommand
.extern FX_DivS32
.extern G2x_ChangeBlendBrightness_
.extern GX_DisableBankForARM7
diff --git a/arm9/lib/include/CARD_common.h b/arm9/lib/include/CARD_common.h
new file mode 100644
index 00000000..1396de12
--- /dev/null
+++ b/arm9/lib/include/CARD_common.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_CARD_COMMON_H_
+#define NITRO_CARD_COMMON_H_
+
+void CARD_Init(void);
+
+#endif //NITRO_CARD_COMMON_H_
diff --git a/arm9/lib/include/CARD_pullOut.h b/arm9/lib/include/CARD_pullOut.h
new file mode 100644
index 00000000..4a64f5ae
--- /dev/null
+++ b/arm9/lib/include/CARD_pullOut.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_CARD_PULLOUT_H_
+#define NITRO_CARD_PULLOUT_H_
+
+BOOL CARD_IsPulledOut(void);
+
+#endif //NITRO_CARD_PULLOUT_H_
diff --git a/arm9/lib/include/CARD_rom.h b/arm9/lib/include/CARD_rom.h
new file mode 100644
index 00000000..4c2e9dd5
--- /dev/null
+++ b/arm9/lib/include/CARD_rom.h
@@ -0,0 +1,39 @@
+#ifndef NITRO_CARD_ROM_H_
+#define NITRO_CARD_ROM_H_
+
+#include "MI_exMemory.h"
+#include "MI_dma.h"
+
+typedef struct
+{
+ u32 offset;
+ u32 length;
+}
+CARDRomRegion;
+
+static inline const CARDRomRegion * CARD_GetRomRegionOVT(MIProcessor target)
+{
+ return (target == MI_PROCESSOR_ARM9)
+ ? (const CARDRomRegion *)((const u8 *)HW_ROM_HEADER_BUF + 0x50)
+ : (const CARDRomRegion *)((const u8 *)HW_ROM_HEADER_BUF + 0x58);
+}
+
+void CARDi_ReadRom(u32 dma, const void * src, void * dst, u32 len, MIDmaCallback done_cb, void * arg, BOOL is_async);
+
+static inline void CARD_ReadRomAsync(u32 dma, const void * src, void * dst, u32 len, MIDmaCallback callback, void * arg)
+{
+ CARDi_ReadRom(dma, src, dst, len, callback, arg, TRUE);
+}
+
+void CARD_LockRom(u16 lock_id);
+void CARD_UnlockRom(u16 lock_id);
+
+static inline const CARDRomRegion * CARD_GetRomRegionFNT() {
+ return (const CARDRomRegion *)((const u8 *)HW_ROM_HEADER_BUF + 0x40);
+}
+
+static inline const CARDRomRegion * CARD_GetRomRegionFAT() {
+ return (const CARDRomRegion *)((const u8 *)HW_ROM_HEADER_BUF + 0x48);
+}
+
+#endif //NITRO_CARD_ROM_H_
diff --git a/arm9/lib/include/DGT_common.h b/arm9/lib/include/DGT_common.h
new file mode 100644
index 00000000..c74ae7cd
--- /dev/null
+++ b/arm9/lib/include/DGT_common.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_DGT_COMMON_H_
+#define NITRO_DGT_COMMON_H_
+
+#define DGT_HASH2_DIGEST_SIZE (160/8)
+
+#endif //NITRO_DGT_COMMON_H_
diff --git a/arm9/lib/include/DGT_dgt.h b/arm9/lib/include/DGT_dgt.h
new file mode 100644
index 00000000..1c48531c
--- /dev/null
+++ b/arm9/lib/include/DGT_dgt.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_DGT_DGT_H_
+#define NITRO_DGT_DGT_H_
+
+void DGT_Hash2CalcHmac(void* digest, void* bin_ptr, int bin_len, void* key_ptr, int keylen);
+
+#endif //NITRO_DGT_DGT_H_
diff --git a/arm9/lib/include/FS_archive.h b/arm9/lib/include/FS_archive.h
new file mode 100644
index 00000000..d30081d7
--- /dev/null
+++ b/arm9/lib/include/FS_archive.h
@@ -0,0 +1,212 @@
+#ifndef NITRO_FS_ARCHIVE_H_
+#define NITRO_FS_ARCHIVE_H_
+
+#include "nitro.h"
+
+#include "OS_thread.h"
+
+struct FSFile;
+struct FSArchive;
+
+#define FS_ARCHIVE_NAME_LEN_MAX 3
+
+#define FS_ARCHIVE_FLAG_REGISTER 0x00000001
+#define FS_ARCHIVE_FLAG_LOADED 0x00000002
+#define FS_ARCHIVE_FLAG_TABLE_LOAD 0x00000004
+#define FS_ARCHIVE_FLAG_SUSPEND 0x00000008
+#define FS_ARCHIVE_FLAG_RUNNING 0x00000010
+#define FS_ARCHIVE_FLAG_CANCELING 0x00000020
+#define FS_ARCHIVE_FLAG_SUSPENDING 0x00000040
+#define FS_ARCHIVE_FLAG_UNLOADING 0x00000080
+#define FS_ARCHIVE_FLAG_IS_ASYNC 0x00000100
+#define FS_ARCHIVE_FLAG_IS_SYNC 0x00000200
+
+typedef enum {
+ FS_COMMAND_ASYNC_BEGIN = 0,
+ FS_COMMAND_READFILE = FS_COMMAND_ASYNC_BEGIN,
+ FS_COMMAND_WRITEFILE,
+ FS_COMMAND_ASYNC_END,
+
+ FS_COMMAND_SYNC_BEGIN = FS_COMMAND_ASYNC_END,
+ FS_COMMAND_SEEKDIR = FS_COMMAND_SYNC_BEGIN,
+ FS_COMMAND_READDIR,
+ FS_COMMAND_FINDPATH,
+ FS_COMMAND_GETPATH,
+ FS_COMMAND_OPENFILEFAST,
+ FS_COMMAND_OPENFILEDIRECT,
+ FS_COMMAND_CLOSEFILE,
+ FS_COMMAND_SYNC_END,
+
+ FS_COMMAND_STATUS_BEGIN = FS_COMMAND_SYNC_END,
+ FS_COMMAND_ACTIVATE = FS_COMMAND_STATUS_BEGIN,
+ FS_COMMAND_IDLE,
+ FS_COMMAND_SUSPEND,
+ FS_COMMAND_RESUME,
+ FS_COMMAND_STATUS_END,
+
+ FS_COMMAND_INVALID
+} FSCommandType;
+
+/* Asynchronous commands*/
+#define FS_ARCHIVE_PROC_READFILE (1 << FS_COMMAND_READFILE)
+#define FS_ARCHIVE_PROC_WRITEFILE (1 << FS_COMMAND_WRITEFILE)
+/* All asynchronous commands*/
+#define FS_ARCHIVE_PROC_ASYNC \
+ (FS_ARCHIVE_PROC_READFILE | FS_ARCHIVE_PROC_WRITEFILE)
+
+/* Synchronous commands*/
+#define FS_ARCHIVE_PROC_SEEKDIR (1 << FS_COMMAND_SEEKDIR)
+#define FS_ARCHIVE_PROC_READDIR (1 << FS_COMMAND_READDIR)
+#define FS_ARCHIVE_PROC_FINDPATH (1 << FS_COMMAND_FINDPATH)
+#define FS_ARCHIVE_PROC_GETPATH (1 << FS_COMMAND_GETPATH)
+#define FS_ARCHIVE_PROC_OPENFILEFAST (1 << FS_COMMAND_OPENFILEFAST)
+#define FS_ARCHIVE_PROC_OPENFILEDIRECT (1 << FS_COMMAND_OPENFILEDIRECT)
+#define FS_ARCHIVE_PROC_CLOSEFILE (1 << FS_COMMAND_CLOSEFILE)
+/* All synchronous commands*/
+#define FS_ARCHIVE_PROC_SYNC \
+ (FS_ARCHIVE_PROC_SEEKDIR | FS_ARCHIVE_PROC_READDIR | \
+ FS_ARCHIVE_PROC_FINDPATH | FS_ARCHIVE_PROC_GETPATH | \
+ FS_ARCHIVE_PROC_OPENFILEFAST | FS_ARCHIVE_PROC_OPENFILEDIRECT | FS_ARCHIVE_PROC_CLOSEFILE)
+
+/* Messages when status changes*/
+#define FS_ARCHIVE_PROC_ACTIVATE (1 << FS_COMMAND_ACTIVATE)
+#define FS_ARCHIVE_PROC_IDLE (1 << FS_COMMAND_IDLE)
+#define FS_ARCHIVE_PROC_SUSPENDING (1 << FS_COMMAND_SUSPEND)
+#define FS_ARCHIVE_PROC_RESUME (1 << FS_COMMAND_RESUME)
+/* All messages when status changes*/
+#define FS_ARCHIVE_PROC_STATUS \
+ (FS_ARCHIVE_PROC_ACTIVATE | FS_ARCHIVE_PROC_IDLE | \
+ FS_ARCHIVE_PROC_SUSPENDING | FS_ARCHIVE_PROC_RESUME)
+
+#define FS_ARCHIVE_PROC_ALL (~0)
+
+typedef enum {
+ FS_RESULT_SUCCESS = 0,
+ FS_RESULT_FAILURE,
+ FS_RESULT_BUSY,
+ FS_RESULT_CANCELED,
+ FS_RESULT_CANCELLED = FS_RESULT_CANCELED, // SDK alias
+ FS_RESULT_UNSUPPORTED,
+ FS_RESULT_ERROR,
+ FS_RESULT_PROC_ASYNC,
+ FS_RESULT_PROC_DEFAULT,
+ FS_RESULT_PROC_UNKNOWN
+}
+FSResult;
+
+typedef FSResult (*FS_ARCHIVE_READ_FUNC) (struct FSArchive *p, void *dst, u32 pos, u32 size);
+typedef FSResult (*FS_ARCHIVE_WRITE_FUNC) (struct FSArchive *p, const void *src, u32 pos, u32 size);
+typedef FSResult (*FS_ARCHIVE_PROC_FUNC) (struct FSFile *, FSCommandType);
+
+typedef struct
+{
+ struct FSFile * prev;
+ struct FSFile * next;
+}
+FSFileLink;
+
+typedef struct
+{
+ u32 start;
+ u16 index;
+ u16 parent;
+} FSArchiveFNT;
+
+typedef struct
+{
+ u32 top;
+ u32 bottom;
+} FSArchiveFAT;
+
+typedef struct FSArchive
+{
+ union
+ {
+ char ptr[4];
+ u32 pack;
+ } name;
+ struct FSArchive * next;
+ struct FSArchive * prev;
+ OSThreadQueue sync_q;
+ OSThreadQueue stat_q;
+ u32 flag;
+ FSFileLink list;
+ u32 base;
+ u32 fat;
+ u32 fat_size;
+ u32 fnt;
+ u32 fnt_size;
+ u32 fat_bak;
+ u32 fnt_bak;
+ void * load_mem;
+ FS_ARCHIVE_READ_FUNC read_func;
+ FS_ARCHIVE_WRITE_FUNC write_func;
+ FS_ARCHIVE_READ_FUNC table_func;
+ FS_ARCHIVE_PROC_FUNC proc;
+ u32 proc_flag;
+} FSArchive;
+
+FSArchive * const FS_FindArchive(const char * path, int offset);
+
+static inline BOOL FS_IsArchiveLoaded(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_LOADED) ? TRUE : FALSE;
+}
+
+static inline u32 FS_GetArchiveOffset(const FSArchive * p_arc, u32 pos)
+{
+ return p_arc->base + pos;
+}
+
+static inline BOOL FSi_IsArchiveCanceling(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_CANCELING) != 0;
+}
+
+static inline BOOL FS_IsArchiveSuspended(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_SUSPEND) ? TRUE : FALSE;
+}
+
+static inline BOOL FSi_IsArchiveSuspending(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_SUSPENDING) != 0;
+}
+
+static inline BOOL FSi_IsArchiveRunning(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_RUNNING) != 0;
+}
+
+static inline BOOL FSi_IsArchiveUnloading(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_UNLOADING) != 0;
+}
+
+static inline BOOL FSi_IsArchiveAsync(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_IS_ASYNC) != 0;
+}
+
+static inline BOOL FSi_IsArchiveSync(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_IS_SYNC) != 0;
+}
+
+static inline BOOL FS_IsArchiveTableLoaded(volatile const FSArchive * p_arc)
+{
+ return (p_arc->flag & FS_ARCHIVE_FLAG_TABLE_LOAD) ? TRUE : FALSE;
+}
+
+BOOL FSi_SendCommand(struct FSFile * file, FSCommandType command);
+BOOL FSi_ExecuteSyncCommand(struct FSFile * file);
+BOOL FS_SuspendArchive(FSArchive * p_arc);
+BOOL FS_ResumeArchive(FSArchive * p_arc);
+void FS_NotifyArchiveAsyncEnd(FSArchive *p_arc, FSResult ret);
+BOOL FS_RegisterArchiveName(FSArchive * p_arc, const char * name, int name_len);
+void FS_InitArchive(FSArchive * p_arc);
+void FS_SetArchiveProc(struct FSArchive * p_arc, FS_ARCHIVE_PROC_FUNC proc, u32 flags);
+BOOL FS_LoadArchive(FSArchive * p_arc, u32 base, u32 fat, u32 fat_size, u32 fnt, u32 fnt_size, FS_ARCHIVE_READ_FUNC read_func, FS_ARCHIVE_WRITE_FUNC write_func);
+u32 FS_LoadArchiveTables(FSArchive *p_arc, void *p_mem, u32 max_size);
+
+#endif //NITRO_FS_ARCHIVE_H_
diff --git a/arm9/lib/include/FS_command.h b/arm9/lib/include/FS_command.h
new file mode 100644
index 00000000..b5e73bcf
--- /dev/null
+++ b/arm9/lib/include/FS_command.h
@@ -0,0 +1,11 @@
+#ifndef NITRO_FS_COMMAND_H_
+#define NITRO_FS_COMMAND_H_
+
+#include "FS_file.h"
+
+extern FSResult (*const fsi_default_command[])(FSFile *);
+
+void FSi_ReleaseCommand(FSFile * file, FSResult signal);
+FSResult FSi_TranslateCommand(FSFile * file, FSCommandType command);
+
+#endif //NITRO_FS_COMMAND_H_
diff --git a/arm9/lib/include/FS_file.h b/arm9/lib/include/FS_file.h
new file mode 100644
index 00000000..3a7d8730
--- /dev/null
+++ b/arm9/lib/include/FS_file.h
@@ -0,0 +1,222 @@
+#ifndef NITRO_FS_FILE_H_
+#define NITRO_FS_FILE_H_
+
+#include "nitro.h"
+
+#include "FS_archive.h"
+
+#define FS_FILE_STATUS_BUSY 0x00000001
+#define FS_FILE_STATUS_CANCEL 0x00000002
+#define FS_FILE_STATUS_SYNC 0x00000004
+#define FS_FILE_STATUS_ASYNC 0x00000008
+#define FS_FILE_STATUS_IS_FILE 0x00000010
+#define FS_FILE_STATUS_IS_DIR 0x00000020
+#define FS_FILE_STATUS_OPERATING 0x00000040
+
+#define FS_FILE_NAME_MAX 127
+
+typedef enum FSSeekFileMode
+{
+ FS_SEEK_SET = 0,
+ FS_SEEK_CUR,
+ FS_SEEK_END
+} FSSeekFileMode;
+
+struct FSFile;
+
+#define FS_DMA_NOT_USE ((u32)~0)
+
+typedef struct FSDirPos
+{
+ struct FSArchive *arc;
+ u16 own_id;
+ u16 index;
+ u32 pos;
+}
+FSDirPos;
+
+typedef struct FSFileID
+{
+ struct FSArchive *arc;
+ u32 file_id;
+}
+FSFileID;
+
+typedef struct
+{
+ union
+ {
+ FSFileID file_id;
+ FSDirPos dir_id;
+ };
+ u32 is_directory;
+ u32 name_len;
+ char name[128];
+}
+FSDirEntry;
+
+
+typedef struct
+{
+ FSDirPos pos;
+}
+FSSeekDirInfo;
+
+
+typedef struct
+{
+ FSDirEntry *p_entry;
+ BOOL skip_string;
+}
+FSReadDirInfo;
+
+
+typedef struct
+{
+ FSDirPos pos;
+ const char *path;
+ BOOL find_directory;
+ union
+ {
+ FSFileID *file;
+ FSDirPos *dir;
+ }
+ result;
+}
+FSFindPathInfo;
+
+
+typedef struct
+{
+ u8 *buf;
+ u32 buf_len;
+ u16 total_len;
+ u16 dir_id;
+}
+FSGetPathInfo;
+
+
+typedef struct
+{
+ FSFileID id;
+}
+FSOpenFileFastInfo;
+
+
+typedef struct
+{
+ u32 top;
+ u32 bottom;
+ u32 index;
+}
+FSOpenFileDirectInfo;
+
+
+typedef struct
+{
+ u32 reserved;
+}
+FSCloseFileInfo;
+
+
+typedef struct
+{
+ void *dst;
+ u32 len_org;
+ u32 len;
+}
+FSReadFileInfo;
+
+
+typedef struct
+{
+ const void *src;
+ u32 len_org;
+ u32 len;
+}
+FSWriteFileInfo;
+
+typedef struct FSFile
+{
+ FSFileLink link;
+ struct FSArchive *arc;
+ u32 stat;
+ FSCommandType command;
+ FSResult error;
+ OSThreadQueue queue[1];
+ union {
+ struct
+ {
+ u32 own_id;
+ u32 top;
+ u32 bottom;
+ u32 pos;
+ } file;
+ struct
+ {
+ FSDirPos pos;
+ u32 parent;
+ } dir;
+ } prop;
+
+ union {
+ FSReadFileInfo readfile;
+ FSWriteFileInfo writefile;
+
+ FSSeekDirInfo seekdir;
+ FSReadDirInfo readdir;
+ FSFindPathInfo findpath;
+ FSGetPathInfo getpath;
+ FSOpenFileFastInfo openfilefast;
+ FSOpenFileDirectInfo openfiledirect;
+ FSCloseFileInfo closefile;
+ } arg;
+}
+FSFile;
+
+u32 FS_SetDefaultDMA(u32 dma_no); // returns the previous selection
+void FS_InitFile(FSFile * p_file);
+BOOL FS_WaitAsync(FSFile * p_file);
+BOOL FS_OpenFileDirect(FSFile * p_file, FSArchive * p_arc, u32 image_top, u32 image_bottom, u32 file_index);
+int FS_ReadFile(FSFile * p_file, void * dst, s32 len);
+int FS_ReadFileAsync(FSFile * p_file, void * dst, s32 len);
+BOOL FS_OpenFile(FSFile * p_file, const char * path);
+BOOL FS_OpenFileFast(FSFile * p_file, FSFileID file_id);
+BOOL FS_CloseFile(FSFile * p_file);
+BOOL FS_SeekFile(FSFile * p_file, int offset, FSSeekFileMode origin);
+
+static inline u32 const FS_GetFileImageTop(volatile const FSFile * p_file) {
+ return p_file->prop.file.top;
+}
+
+static inline u32 const FS_GetLength(volatile const FSFile * p_file)
+{
+ return p_file->prop.file.bottom - p_file->prop.file.top;
+}
+
+static inline BOOL FS_IsCanceling(volatile const FSFile * p_file)
+{
+ return (p_file->stat & FS_FILE_STATUS_CANCEL) ? TRUE : FALSE;
+}
+
+static inline BOOL FS_IsFileSyncMode(volatile const FSFile * p_file)
+{
+ return (p_file->stat & FS_FILE_STATUS_SYNC) ? TRUE : FALSE;
+}
+
+static inline BOOL FS_IsBusy(volatile const FSFile * p_file)
+{
+ return p_file->stat & FS_FILE_STATUS_BUSY ? TRUE : FALSE;
+}
+
+static inline BOOL FS_IsSucceeded(volatile const FSFile * p_file)
+{
+ return (p_file->error == FS_RESULT_SUCCESS) ? TRUE : FALSE;
+}
+
+static inline BOOL FS_IsDir(volatile const FSFile * p_file)
+{
+ return (p_file->stat & FS_FILE_STATUS_IS_DIR) ? TRUE : FALSE;
+}
+
+#endif //NITRO_FS_FILE_H_
diff --git a/arm9/lib/include/FS_mw_dtor.h b/arm9/lib/include/FS_mw_dtor.h
new file mode 100644
index 00000000..a746ed19
--- /dev/null
+++ b/arm9/lib/include/FS_mw_dtor.h
@@ -0,0 +1,16 @@
+#ifndef NITRO_FS_MW_DTOR_H_
+#define NITRO_FS_MW_DTOR_H_
+
+typedef void (*MWI_DESTRUCTOR_FUNC) (void *);
+
+typedef struct MWiDestructorChain
+{
+ struct MWiDestructorChain *next;
+ MWI_DESTRUCTOR_FUNC dtor;
+ void *obj;
+}
+MWiDestructorChain;
+
+extern MWiDestructorChain *__global_destructor_chain;
+
+#endif //NITRO_FS_MW_DTOR_H_
diff --git a/arm9/lib/include/FS_overlay.h b/arm9/lib/include/FS_overlay.h
new file mode 100644
index 00000000..6025d04a
--- /dev/null
+++ b/arm9/lib/include/FS_overlay.h
@@ -0,0 +1,55 @@
+#ifndef NITRO_FS_OVERLAY_H_
+#define NITRO_FS_OVERLAY_H_
+
+#include "nitro.h"
+#include "MI_exMemory.h"
+#include "FS_file.h"
+#include "CARD_rom.h"
+
+typedef u32 FSOverlayID;
+
+typedef void (*FSOverlayInitFunc) (void);
+
+typedef struct FSOverlayInfoHeader
+{
+ u32 id;
+ u8 *ram_address;
+ u32 ram_size;
+ u32 bss_size;
+ FSOverlayInitFunc *sinit_init;
+ FSOverlayInitFunc *sinit_init_end;
+ u32 file_id;
+ u32 compressed:24;
+ u32 flag:8;
+} FSOverlayInfoHeader;
+
+typedef struct FSOverlayInfo
+{
+ FSOverlayInfoHeader header;
+ MIProcessor target;
+ CARDRomRegion file_pos;
+} FSOverlayInfo;
+
+static inline u8 *const FS_GetOverlayAddress(FSOverlayInfo * p_ovi)
+{
+ return p_ovi->header.ram_address;
+}
+
+static inline u32 const FS_GetOverlayImageSize(FSOverlayInfo * p_ovi)
+{
+ return p_ovi->header.ram_size;
+}
+
+static inline u32 const FS_GetOverlayTotalSize(FSOverlayInfo * p_ovi)
+{
+ return p_ovi->header.ram_size + p_ovi->header.bss_size;
+}
+
+BOOL FS_LoadOverlayInfo(FSOverlayInfo *p_ovi, MIProcessor target, FSOverlayID id);
+BOOL FS_LoadOverlay(MIProcessor target, FSOverlayID id);
+BOOL FS_UnloadOverlay(MIProcessor target, FSOverlayID id);
+BOOL FS_LoadOverlayImage(FSOverlayInfo *p_ovi);
+void FS_StartOverlay(FSOverlayInfo *p_ovi);
+BOOL FS_LoadOverlayImageAsync(FSOverlayInfo *p_ovi, FSFile *p_file);
+
+#endif //NITRO_FS_OVERLAY_H_
diff --git a/arm9/lib/include/FS_rom.h b/arm9/lib/include/FS_rom.h
new file mode 100644
index 00000000..ac8ad8fb
--- /dev/null
+++ b/arm9/lib/include/FS_rom.h
@@ -0,0 +1,14 @@
+#ifndef NITRO_FS_ROM_H_
+#define NITRO_FS_ROM_H_
+
+#include "FS_archive.h"
+#include "CARD_rom.h"
+
+extern FSArchive fsi_arc_rom;
+extern s32 fsi_card_lock_id;
+extern CARDRomRegion fsi_ovt7;
+extern CARDRomRegion fsi_ovt9;
+
+void FSi_InitRom(u32 default_dma_no);
+
+#endif //NITRO_FS_ROM_H_
diff --git a/arm9/lib/include/FSi_util.h b/arm9/lib/include/FSi_util.h
new file mode 100644
index 00000000..6e96681e
--- /dev/null
+++ b/arm9/lib/include/FSi_util.h
@@ -0,0 +1,46 @@
+#ifndef NITRO_FSI_UTIL_H_
+#define NITRO_FSI_UTIL_H_
+
+#define ALIGN_MASK(a) ((u32)((a) - 1))
+
+#define ALIGN_BYTE(n, a) (((u32)(n) + ALIGN_MASK(a)) & ~ALIGN_MASK(a))
+
+#define BIT_MASK(a) ((u32)((1 << (a)) - 1))
+
+static inline BOOL FSi_IsSlash(u32 c)
+{
+ return (c == '/') || (c == '\\');
+}
+
+static inline void FSi_CutFromListCore(FSFileLink *trg)
+{
+ FSFile *const pr = trg->prev;
+ FSFile *const nx = trg->next;
+ if (pr)
+ pr->link.next = nx;
+ if (nx)
+ nx->link.prev = pr;
+}
+
+static inline void FSi_CutFromList(FSFile *elem)
+{
+ FSFileLink *const trg = &elem->link;
+ FSi_CutFromListCore(trg);
+ trg->next = trg->prev = NULL;
+}
+
+static inline void FSi_AppendToList(FSFile *elem, FSFile *list)
+{
+ FSFileLink *const trg = &elem->link;
+ FSi_CutFromListCore(trg);
+ {
+ while (list->link.next)
+ list = list->link.next;
+ list->link.next = elem;
+ trg->prev = list;
+ trg->next = NULL;
+ }
+}
+
+
+#endif //NITRO_FSI_UTIL_H_
diff --git a/arm9/lib/include/MI_byteAccess.h b/arm9/lib/include/MI_byteAccess.h
new file mode 100644
index 00000000..cad4d518
--- /dev/null
+++ b/arm9/lib/include/MI_byteAccess.h
@@ -0,0 +1,14 @@
+#ifndef NITRO_MI_BYTEACCESS_H_
+#define NITRO_MI_BYTEACCESS_H_
+
+static inline u8 MI_ReadByte(const void *address)
+{
+ return *(u8 *)address;
+}
+
+static inline void MI_WriteByte(void *address, u8 value)
+{
+ *(u8 *)address = value;
+}
+
+#endif //NITRO_MI_BYTEACCESS_H_
diff --git a/arm9/lib/include/MI_dma.h b/arm9/lib/include/MI_dma.h
new file mode 100644
index 00000000..eddcedbb
--- /dev/null
+++ b/arm9/lib/include/MI_dma.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_MI_DMA_H_
+#define NITRO_MI_DMA_H_
+
+typedef void (*MIDmaCallback)(void *);
+
+#endif //NITRO_MI_DMA_H_
diff --git a/arm9/lib/include/MI_exMemory.h b/arm9/lib/include/MI_exMemory.h
new file mode 100644
index 00000000..4a8a10a8
--- /dev/null
+++ b/arm9/lib/include/MI_exMemory.h
@@ -0,0 +1,9 @@
+#ifndef NITRO_MI_EXMEMORY_H_
+#define NITRO_MI_EXMEMORY_H_
+
+typedef enum {
+ MI_PROCESSOR_ARM9 = 0,
+ MI_PROCESSOR_ARM7 = 1
+} MIProcessor;
+
+#endif //NITRO_MI_EXMEMORY_H_
diff --git a/arm9/lib/include/MI_memory.h b/arm9/lib/include/MI_memory.h
new file mode 100644
index 00000000..d9935a5f
--- /dev/null
+++ b/arm9/lib/include/MI_memory.h
@@ -0,0 +1,10 @@
+#ifndef NITRO_MI_MEMORY_H_
+#define NITRO_MI_MEMORY_H_
+
+void MI_CpuFill8(void *dest, u8 data, u32 size);
+void MI_CpuCopy8(void const *src, void *dest, u32 size);
+static inline void MI_CpuClear8(void *dest, u32 size) {
+ MI_CpuFill8(dest, 0, size);
+}
+
+#endif //NITRO_MI_MEMORY_H_
diff --git a/arm9/lib/include/MI_uncompress.h b/arm9/lib/include/MI_uncompress.h
new file mode 100644
index 00000000..55f28e27
--- /dev/null
+++ b/arm9/lib/include/MI_uncompress.h
@@ -0,0 +1,6 @@
+#ifndef NITRO_MI_UNCOMPRESS_H_
+#define NITRO_MI_UNCOMPRESS_H_
+
+void MIi_UncompressBackward(void * bottom);
+
+#endif //NITRO_MI_UNCOMPRESS_H_
diff --git a/arm9/lib/include/OS_cache.h b/arm9/lib/include/OS_cache.h
new file mode 100644
index 00000000..bee42d45
--- /dev/null
+++ b/arm9/lib/include/OS_cache.h
@@ -0,0 +1,9 @@
+#ifndef NITRO_OS_CACHE_H_
+#define NITRO_OS_CACHE_H_
+
+void IC_InvalidateRange(void *startAddr, u32 nBytes);
+void IC_FlushRange(void *startAddr, u32 nBytes);
+void DC_InvalidateRange(void *startAddr, u32 nBytes);
+void DC_FlushRange(void *startAddr, u32 nBytes);
+
+#endif //NITRO_OS_CACHE_H_
diff --git a/arm9/lib/include/OS_printf.h b/arm9/lib/include/OS_printf.h
new file mode 100644
index 00000000..7c02252b
--- /dev/null
+++ b/arm9/lib/include/OS_printf.h
@@ -0,0 +1,8 @@
+#ifndef NITRO_OS_PRINTF_H_
+#define NITRO_OS_PRINTF_H_
+
+#define OS_Warning( ... ) ((void)0)
+#define OS_TPanic(...) OS_Terminate()
+#define OS_TWarning(...) ((void)0)
+
+#endif //NITRO_OS_PRINTF_H_
diff --git a/arm9/lib/include/OS_spinLock.h b/arm9/lib/include/OS_spinLock.h
index b7f0a571..3bb8a1c2 100644
--- a/arm9/lib/include/OS_spinLock.h
+++ b/arm9/lib/include/OS_spinLock.h
@@ -11,4 +11,6 @@ typedef volatile struct OSLockWord {
u16 extension;
} OSLockWord;
+s32 OS_GetLockID(void);
+
#endif //POKEDIAMOND_OS_SPINLOCK_H
diff --git a/arm9/lib/include/OS_system.h b/arm9/lib/include/OS_system.h
index 9a79c0d1..794e16d2 100644
--- a/arm9/lib/include/OS_system.h
+++ b/arm9/lib/include/OS_system.h
@@ -5,8 +5,8 @@
#ifndef POKEDIAMOND_OS_SYSTEM_H
#define POKEDIAMOND_OS_SYSTEM_H
-#include "consts.h"
#include "function_target.h"
+#include "consts.h"
typedef enum {
OS_PROCMODE_USER=16,
diff --git a/arm9/lib/include/OS_thread.h b/arm9/lib/include/OS_thread.h
index 49ae9f15..15cec0c9 100644
--- a/arm9/lib/include/OS_thread.h
+++ b/arm9/lib/include/OS_thread.h
@@ -28,6 +28,9 @@ struct _OSThread
u8 padding[0x80]; //todo: not the correct size but idfk
};
+void OS_SleepThread(OSThreadQueue * queue);
+void OS_WakeupThread(OSThreadQueue * queue);
+
static inline void OS_InitThreadQueue(OSThreadQueue * queue)
{
queue->head = queue->tail = NULL;
diff --git a/arm9/lib/include/mmap.h b/arm9/lib/include/mmap.h
index 1f8f37f9..27255115 100644
--- a/arm9/lib/include/mmap.h
+++ b/arm9/lib/include/mmap.h
@@ -12,8 +12,10 @@ extern u32 SDK_AUTOLOAD_DTCM_START[];
#define HW_MAIN_MEM_SHARED_SIZE 0x00001000
#define HW_MAIN_MEM_DEBUGGER_OFFSET 0x00700000
+#define HW_ITCM_IMAGE 0x01000000
#define HW_ITCM 0x01FF8000
#define HW_ITCM_SIZE 0x00008000
+#define HW_ITCM_END (HW_ITCM + HW_ITCM_SIZE)
#define HW_WRAM 0x037F8000
diff --git a/arm9/lib/src/FS_archive.c b/arm9/lib/src/FS_archive.c
new file mode 100644
index 00000000..6c0f01f1
--- /dev/null
+++ b/arm9/lib/src/FS_archive.c
@@ -0,0 +1,445 @@
+#include "FS_archive.h"
+#include "FS_file.h"
+#include "FS_command.h"
+#include "FSi_util.h"
+#include "MI_memory.h"
+#include "MI_byteAccess.h"
+#include "OS_printf.h"
+
+FSArchive * arc_list = NULL;
+FSDirPos current_dir_pos;
+
+ARM_FUNC u32 FSi_GetPackedName(const char * name, int name_len)
+{
+ u32 ret = 0;
+ if (name_len <= FS_ARCHIVE_NAME_LEN_MAX)
+ {
+ int i = 0;
+ for (; i < name_len; i++)
+ {
+ u32 c = MI_ReadByte(name + i);
+ if (!c)
+ break;
+ c = (u32)(c - 'A');
+ if (c <= (u32)('Z' - 'A'))
+ c = (u32)(c + 'a');
+ else
+ c = (u32)(c + 'A');
+ ret |= (u32)(c << (i * 8));
+ }
+ }
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_ReadMemCallback(struct FSArchive * p_arc, void * dest, u32 pos, u32 size)
+{
+ MI_CpuCopy8((const void *)FS_GetArchiveOffset(p_arc, pos), dest, size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_WriteMemCallback(struct FSArchive * p_arc, const void * src, u32 pos, u32 size)
+{
+ MI_CpuCopy8(src, (void *)FS_GetArchiveOffset(p_arc, pos), size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_ReadMemoryCore(FSArchive * p_arc, void * dest, u32 pos, u32 size)
+{
+ MI_CpuCopy8((const void *)pos, dest, size);
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSFile * FSi_NextCommand(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FSi_IsArchiveCanceling(p_arc))
+ {
+ FSFile *p, *q;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_CANCELING;
+ for (p = p_arc->list.next; p; p = q)
+ {
+ q = p->link.next;
+ if (FS_IsCanceling(p))
+ {
+ if (p_arc->list.next == p)
+ p_arc->list.next = q;
+ FSi_ReleaseCommand(p, FS_RESULT_CANCELED);
+ if (!q)
+ q = p_arc->list.next;
+ }
+ }
+ }
+ if (!FSi_IsArchiveSuspending(p_arc) && !FS_IsArchiveSuspended(p_arc))
+ {
+ FSFile * p_file = p_arc->list.next;
+ if (p_file != NULL)
+ {
+ const BOOL is_start = !FSi_IsArchiveRunning(p_arc);
+ if (is_start)
+ p_arc->flag |= FS_ARCHIVE_FLAG_RUNNING;
+ OS_RestoreInterrupts(bak_psr);
+ if (is_start)
+ {
+ if ((p_arc->proc_flag & FS_ARCHIVE_PROC_ACTIVATE) != 0)
+ (*p_arc->proc) (p_file, FS_COMMAND_ACTIVATE);
+ }
+ bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OS_WakeupThread(p_file->queue);
+ OS_RestoreInterrupts(bak_psr);
+ return NULL;
+ }
+ OS_RestoreInterrupts(bak_psr);
+ return p_file;
+ }
+ }
+ if (FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_RUNNING;
+ if (p_arc->proc_flag & FS_ARCHIVE_PROC_IDLE)
+ {
+ FSFile tmp;
+ FS_InitFile(&tmp);
+ tmp.arc = p_arc;
+ (*p_arc->proc)(&tmp, FS_COMMAND_IDLE);
+ }
+ }
+ if (FSi_IsArchiveSuspending(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_SUSPENDING;
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPEND;
+ OS_WakeupThread(&p_arc->stat_q);
+ }
+ OS_RestoreInterrupts(bak_psr);
+ return NULL;
+}
+
+ARM_FUNC void FSi_ExecuteAsyncCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ while (p_file)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OS_WakeupThread(p_file->queue);
+ OS_RestoreInterrupts(bak_psr);
+ break;
+ }
+ p_file->stat |= FS_FILE_STATUS_ASYNC;
+ OS_RestoreInterrupts(bak_psr);
+ if (FSi_TranslateCommand(p_file, p_file->command) == FS_RESULT_PROC_ASYNC)
+ break;
+ p_file = FSi_NextCommand(p_arc);
+ }
+}
+
+ARM_FUNC BOOL FSi_ExecuteSyncCommand(FSFile * p_file)
+{
+ FSFile * p_target;
+ FSResult ret = FSi_TranslateCommand(p_file, p_file->command);
+ FSi_ReleaseCommand(p_file, ret);
+ p_target = FSi_NextCommand(p_file->arc);
+ if (p_target)
+ FSi_ExecuteAsyncCommand(p_target);
+ return FS_IsSucceeded(p_file);
+}
+
+ARM_FUNC BOOL FSi_SendCommand(FSFile * p_file, FSCommandType command)
+{
+ FSArchive * p_arc = p_file->arc;
+ const int bit = 1 << command;
+ p_file->command = command;
+ p_file->error = FS_RESULT_BUSY;
+ p_file->stat |= FS_FILE_STATUS_BUSY;
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FSi_IsArchiveUnloading(p_arc))
+ {
+ FSi_ReleaseCommand(p_file, FS_RESULT_CANCELLED);
+ OS_RestoreInterrupts(bak_psr);
+ return FALSE;
+ }
+ if ((bit & FS_ARCHIVE_PROC_SYNC) != 0)
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ FSi_AppendToList(p_file, (FSFile *)&p_arc->list);
+ if (!FS_IsArchiveSuspended(p_arc) && !FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_RUNNING;
+ OS_RestoreInterrupts(bak_psr);
+ if ((p_arc->proc_flag & FS_ARCHIVE_PROC_ACTIVATE))
+ (*p_arc->proc)(p_file, FS_COMMAND_ACTIVATE);
+ bak_psr = OS_DisableInterrupts();
+ p_file->stat |= FS_FILE_STATUS_OPERATING;
+ if (!FS_IsFileSyncMode(p_file))
+ {
+ OS_RestoreInterrupts(bak_psr);
+ FSi_ExecuteAsyncCommand(p_file);
+ return TRUE;
+ }
+ OS_RestoreInterrupts(bak_psr);
+ }
+ else if (!FS_IsFileSyncMode(p_file))
+ {
+ OS_RestoreInterrupts(bak_psr);
+ return TRUE;
+ }
+ else
+ {
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (!(p_file->stat & FS_FILE_STATUS_OPERATING));
+ OS_RestoreInterrupts(bak_psr);
+ }
+ }
+ return FSi_ExecuteSyncCommand(p_file);
+}
+
+ARM_FUNC void FS_InitArchive(FSArchive * p_arc)
+{
+ MI_CpuClear8(p_arc, sizeof(FSArchive));
+ p_arc->sync_q.head = p_arc->sync_q.tail = NULL;
+ p_arc->stat_q.head = p_arc->stat_q.tail = NULL;
+}
+
+ARM_FUNC FSArchive * const FS_FindArchive(const char * name, int name_len)
+{
+ u32 pack = FSi_GetPackedName(name, name_len);
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ FSArchive * p_arc = arc_list;
+ while (p_arc && (p_arc->name.pack != pack))
+ p_arc = p_arc->next;
+ OS_RestoreInterrupts(bak_psr);
+ return p_arc;
+}
+
+ARM_FUNC BOOL FS_RegisterArchiveName(FSArchive * p_arc, const char * name, int name_len)
+{
+ BOOL ret = FALSE;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (!FS_FindArchive(name, name_len))
+ {
+ FSArchive * p_tail = arc_list;
+ if (!p_tail)
+ {
+ arc_list = p_arc;
+ current_dir_pos.arc = p_arc;
+ current_dir_pos.pos = 0;
+ current_dir_pos.index = 0;
+ current_dir_pos.own_id = 0;
+ }
+ else
+ {
+ while (p_tail->next)
+ p_tail = p_tail->next;
+ p_tail->next = p_arc;
+ p_arc->prev = p_tail;
+ }
+ p_arc->name.pack = FSi_GetPackedName(name, name_len);
+ p_arc->flag |= FS_ARCHIVE_FLAG_REGISTER;
+ ret = TRUE;
+ }
+ OS_RestoreInterrupts(bak_psr);
+ return ret;
+}
+
+ARM_FUNC void FS_ReleaseArchiveName(FSArchive * p_arc)
+{
+ if (p_arc->name.pack)
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (p_arc->next)
+ p_arc->next->prev = p_arc->prev;
+ if (p_arc->prev)
+ p_arc->prev->next = p_arc->next;
+ p_arc->name.pack = 0;
+ p_arc->next = p_arc->prev = NULL;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_REGISTER;
+ if (current_dir_pos.arc == p_arc)
+ {
+ current_dir_pos.arc = arc_list;
+ current_dir_pos.pos = 0;
+ current_dir_pos.index = 0;
+ current_dir_pos.own_id = 0;
+ }
+ OS_RestoreInterrupts(bak_psr);
+ }
+}
+
+ARM_FUNC BOOL FS_LoadArchive(FSArchive * p_arc, u32 base, u32 fat, u32 fat_size, u32 fnt, u32 fnt_size, FS_ARCHIVE_READ_FUNC read_func, FS_ARCHIVE_WRITE_FUNC write_func)
+{
+ p_arc->base = base;
+ p_arc->fat_size = fat_size;
+ p_arc->fat = p_arc->fat_bak = fat;
+ p_arc->fnt_size = fnt_size;
+ p_arc->fnt = p_arc->fnt_bak = fnt;
+ p_arc->read_func = (read_func != NULL) ? read_func : FSi_ReadMemCallback;
+ p_arc->write_func = (write_func != NULL) ? write_func : FSi_WriteMemCallback;
+ p_arc->table_func = p_arc->read_func;
+ p_arc->load_mem = NULL;
+ p_arc->flag |= FS_ARCHIVE_FLAG_LOADED;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_UnloadArchive(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ if (FS_IsArchiveLoaded(p_arc))
+ {
+ if (FS_IsArchiveTableLoaded(p_arc))
+ {
+ OS_TWarning("memory may leak. preloaded-table of archive \"%s\" (0x%08X)", p_arc->name.ptr, p_arc->load_mem);
+ }
+ {
+ FSFile *p, *q;
+ BOOL bak_state = FS_SuspendArchive(p_arc);
+ p_arc->flag |= FS_ARCHIVE_FLAG_UNLOADING;
+ for (p = p_arc->list.next; p; p = q)
+ {
+ q = p->link.next;
+ FSi_ReleaseCommand(p, FS_RESULT_CANCELED);
+ }
+ p_arc->list.next = NULL;
+ if (bak_state)
+ FS_ResumeArchive(p_arc);
+ }
+ p_arc->base = 0;
+ p_arc->fat = 0;
+ p_arc->fat_size = 0;
+ p_arc->fnt = 0;
+ p_arc->fnt_size = 0;
+ p_arc->fat_bak = p_arc->fnt_bak = 0;
+ p_arc->flag &= ~(FS_ARCHIVE_FLAG_CANCELING | FS_ARCHIVE_FLAG_LOADED | FS_ARCHIVE_FLAG_UNLOADING);
+ }
+ OS_RestoreInterrupts(bak_psr);
+ return TRUE;
+}
+
+ARM_FUNC u32 FS_LoadArchiveTables(FSArchive *p_arc, void *p_mem, u32 max_size)
+{
+ u32 total_size = ALIGN_BYTE(p_arc->fat_size + p_arc->fnt_size + 32, 32);
+ if (total_size <= max_size)
+ {
+ u8 *p_cache = (u8 *)ALIGN_BYTE((u32)p_mem, 32);
+ FSFile tmp;
+ FS_InitFile(&tmp);
+ if (FS_OpenFileDirect(&tmp, p_arc, p_arc->fat, p_arc->fat + p_arc->fat_size, (u32)~0))
+ {
+ if (FS_ReadFile(&tmp, p_cache, (s32)p_arc->fat_size) < 0)
+ {
+ MI_CpuFill8(p_cache, 0x00, p_arc->fat_size);
+ }
+ FS_CloseFile(&tmp);
+ }
+ p_arc->fat = (u32)p_cache;
+ p_cache += p_arc->fat_size;
+ if (FS_OpenFileDirect(&tmp, p_arc, p_arc->fnt, p_arc->fnt + p_arc->fnt_size, (u32)~0))
+ {
+ if (FS_ReadFile(&tmp, p_cache, (s32)p_arc->fnt_size) < 0)
+ {
+ MI_CpuFill8(p_cache, 0x00, p_arc->fnt_size);
+ }
+ FS_CloseFile(&tmp);
+ }
+ p_arc->fnt = (u32)p_cache;
+ p_arc->load_mem = p_mem;
+ p_arc->table_func = FSi_ReadMemoryCore;
+ p_arc->flag |= FS_ARCHIVE_FLAG_TABLE_LOAD;
+ }
+ return total_size;
+}
+
+ARM_FUNC void * FS_UnloadArchiveTables(FSArchive * p_arc)
+{
+ void *ret = NULL;
+ if (FS_IsArchiveLoaded(p_arc))
+ {
+ BOOL bak_stat = FS_SuspendArchive(p_arc);
+ if (FS_IsArchiveTableLoaded(p_arc))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_TABLE_LOAD;
+ ret = p_arc->load_mem;
+ p_arc->load_mem = NULL;
+ p_arc->fat = p_arc->fat_bak;
+ p_arc->fnt = p_arc->fnt_bak;
+ p_arc->table_func = p_arc->read_func;
+ }
+ if (bak_stat)
+ FS_ResumeArchive(p_arc);
+ }
+ return ret;
+}
+
+ARM_FUNC BOOL FS_SuspendArchive(FSArchive * p_arc)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ const BOOL bak_stat = !FS_IsArchiveSuspended(p_arc);
+ if (bak_stat)
+ {
+ if (FSi_IsArchiveRunning(p_arc))
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPENDING;
+ do {
+ OS_SleepThread(&p_arc->stat_q);
+ } while (FSi_IsArchiveSuspending(p_arc));
+ }
+ else
+ {
+ p_arc->flag |= FS_ARCHIVE_FLAG_SUSPEND;
+ }
+ }
+ OS_RestoreInterrupts(bak_psr);
+ return bak_stat;
+}
+
+ARM_FUNC BOOL FS_ResumeArchive(FSArchive * p_arc)
+{
+ FSFile * p_target = NULL;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ const BOOL bak_stat = !FS_IsArchiveSuspended(p_arc);
+ if (!bak_stat)
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_SUSPEND;
+ p_target = FSi_NextCommand(p_arc);
+ }
+ OS_RestoreInterrupts(bak_psr);
+ if (p_target)
+ FSi_ExecuteAsyncCommand(p_target);
+ return bak_stat;
+}
+
+ARM_FUNC void FS_SetArchiveProc(struct FSArchive * p_arc, FS_ARCHIVE_PROC_FUNC proc, u32 flags)
+{
+ if (!flags)
+ proc = NULL;
+ else if (!proc)
+ flags = 0;
+ p_arc->proc = proc;
+ p_arc->proc_flag = flags;
+}
+
+ARM_FUNC void FS_NotifyArchiveAsyncEnd(FSArchive *p_arc, FSResult ret)
+{
+ if (FSi_IsArchiveAsync(p_arc))
+ {
+ FSFile *p_file = p_arc->list.next;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_ASYNC;
+ FSi_ReleaseCommand(p_file, ret);
+ p_file = FSi_NextCommand(p_arc);
+ if (p_file)
+ FSi_ExecuteAsyncCommand(p_file);
+ }
+ else
+ {
+ FSFile *p_file = p_arc->list.next;
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ p_file->error = ret;
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ OS_WakeupThread(&p_arc->sync_q);
+ (void)OS_RestoreInterrupts(bak_psr);
+ }
+}
diff --git a/arm9/lib/src/FS_command.c b/arm9/lib/src/FS_command.c
new file mode 100644
index 00000000..818a65ea
--- /dev/null
+++ b/arm9/lib/src/FS_command.c
@@ -0,0 +1,75 @@
+#include "FS_file.h"
+#include "FS_archive.h"
+#include "FSi_util.h"
+#include "FS_command.h"
+
+ARM_FUNC void FSi_ReleaseCommand(FSFile * p_file, FSResult ret)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ FSi_CutFromList(p_file);
+ p_file->stat &= ~(FS_FILE_STATUS_CANCEL | FS_FILE_STATUS_BUSY | FS_FILE_STATUS_SYNC | FS_FILE_STATUS_ASYNC | FS_FILE_STATUS_OPERATING);
+ p_file->error = ret;
+ OS_WakeupThread(p_file->queue);
+ OS_RestoreInterrupts(bak_psr);
+}
+
+ARM_FUNC FSResult FSi_TranslateCommand(FSFile *p_file, FSCommandType command)
+{
+ FSResult ret;
+
+ FSArchive *const p_arc = p_file->arc;
+ const int bit = (1 << command);
+
+ if (FS_IsFileSyncMode(p_file))
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC;
+ else
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_ASYNC;
+
+ if ((p_arc->proc_flag & bit) != 0)
+ {
+ switch (ret = (*p_arc->proc) (p_file, command))
+ {
+ case FS_RESULT_SUCCESS:
+ case FS_RESULT_FAILURE:
+ case FS_RESULT_UNSUPPORTED:
+ p_file->error = ret;
+ break;
+ case FS_RESULT_PROC_ASYNC:
+ break;
+ case FS_RESULT_PROC_UNKNOWN:
+ ret = FS_RESULT_PROC_DEFAULT;
+ p_arc->proc_flag &= ~bit;
+ break;
+ }
+ }
+ else
+ {
+ ret = FS_RESULT_PROC_DEFAULT;
+ }
+ if (ret == FS_RESULT_PROC_DEFAULT)
+ {
+ ret = (*fsi_default_command[command]) (p_file);
+ }
+ if (ret == FS_RESULT_PROC_ASYNC)
+ {
+ if (FS_IsFileSyncMode(p_file))
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while (FSi_IsArchiveSync(p_arc))
+ OS_SleepThread(&p_arc->sync_q);
+ ret = p_file->error;
+ OS_RestoreInterrupts(bak_psr);
+ }
+ }
+ else if (!FS_IsFileSyncMode(p_file))
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_ASYNC;
+ FSi_ReleaseCommand(p_file, ret);
+ }
+ else
+ {
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ p_file->error = ret;
+ }
+ return ret;
+}
diff --git a/arm9/lib/src/FS_command_default.c b/arm9/lib/src/FS_command_default.c
new file mode 100644
index 00000000..002e1d53
--- /dev/null
+++ b/arm9/lib/src/FS_command_default.c
@@ -0,0 +1,468 @@
+#include "nitro.h"
+#include "FS_file.h"
+#include "FS_command.h"
+#include "FS_archive.h"
+#include "MI_byteAccess.h"
+#include "MI_memory.h"
+#include "FSi_util.h"
+
+typedef struct
+{
+ FSArchive *arc;
+ u32 pos;
+}
+FSiSyncReadParam;
+
+ARM_FUNC FSResult FSi_ReadFileCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_WriteFileCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_SeekDirCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_ReadDirCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_FindPathCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_GetPathCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_OpenFileFastCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_OpenFileDirectCommand(FSFile * p_file);
+ARM_FUNC FSResult FSi_CloseFileCommand(FSFile * p_file);
+
+FSResult (*const fsi_default_command[])(FSFile *) = {
+ [FS_COMMAND_READFILE] = FSi_ReadFileCommand,
+ [FS_COMMAND_WRITEFILE] = FSi_WriteFileCommand,
+ [FS_COMMAND_SEEKDIR] = FSi_SeekDirCommand,
+ [FS_COMMAND_READDIR] = FSi_ReadDirCommand,
+ [FS_COMMAND_FINDPATH] = FSi_FindPathCommand,
+ [FS_COMMAND_GETPATH] = FSi_GetPathCommand,
+ [FS_COMMAND_OPENFILEFAST] = FSi_OpenFileFastCommand,
+ [FS_COMMAND_OPENFILEDIRECT] = FSi_OpenFileDirectCommand,
+ [FS_COMMAND_CLOSEFILE] = FSi_CloseFileCommand,
+};
+
+// Case-insensitive string comparison
+ARM_FUNC u32 FSi_StrNICmp(const char * str1, const char * str2, u32 len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ u32 c = MI_ReadByte(str1 + i) - 'A';
+ u32 d = MI_ReadByte(str2 + i) - 'A';
+ if (c <= 'Z' - 'A')
+ c += 'a' - 'A';
+ if (d <= 'Z' - 'A')
+ d += 'a' - 'A';
+ if (c != d)
+ return c - d;
+ }
+ return 0;
+}
+
+ARM_FUNC FSResult FSi_ReadTable(FSiSyncReadParam * p, void * dst, u32 len)
+{
+ FSResult ret;
+ FSArchive * const p_arc = p->arc;
+ p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC;
+ switch (ret = (*p_arc->table_func)(p_arc, dst, p->pos, len))
+ {
+ case FS_RESULT_SUCCESS:
+ case FS_RESULT_FAILURE:
+ p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
+ break;
+ case FS_RESULT_PROC_ASYNC:
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ while (FSi_IsArchiveSync(p_arc))
+ OS_SleepThread(&p_arc->sync_q);
+ OS_RestoreInterrupts(bak_psr);
+ ret = p_arc->list.next->error;
+ }
+ break;
+ }
+ p->pos += len;
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_SeekDirDirect(FSFile * p_dir, u32 id)
+{
+ p_dir->stat |= FS_FILE_STATUS_SYNC;
+ p_dir->arg.seekdir.pos.arc = p_dir->arc;
+ p_dir->arg.seekdir.pos.pos = 0;
+ p_dir->arg.seekdir.pos.index = 0;
+ p_dir->arg.seekdir.pos.own_id = (u16)id;
+ return FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+}
+
+// The actual commands
+ARM_FUNC FSResult FSi_ReadFileCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const u32 pos = p_file->prop.file.pos;
+ const u32 len = p_file->arg.readfile.len;
+ void *const dst = p_file->arg.readfile.dst;
+ p_file->prop.file.pos += len;
+ return (*p_arc->read_func)(p_arc, dst, pos, len);
+}
+
+ARM_FUNC FSResult FSi_WriteFileCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const u32 pos = p_file->prop.file.pos;
+ const u32 len = p_file->arg.writefile.len;
+ const void *const src = p_file->arg.writefile.src;
+ p_file->prop.file.pos += len;
+ return (*p_arc->write_func)(p_arc, src, pos, len);
+}
+
+ARM_FUNC FSResult FSi_SeekDirCommand(FSFile * p_dir)
+{
+ FSResult ret;
+ FSArchive *const p_arc = p_dir->arc;
+ const FSDirPos *const arg = &p_dir->arg.seekdir.pos;
+
+ FSArchiveFNT fnt_entry;
+ FSiSyncReadParam param;
+ param.arc = p_arc;
+ param.pos = p_arc->fnt + arg->own_id * sizeof(fnt_entry);
+ ret = FSi_ReadTable(&param, &fnt_entry, sizeof(fnt_entry));
+ if (ret == FS_RESULT_SUCCESS)
+ {
+ p_dir->prop.dir.pos = *arg;
+ if ((arg->index == 0) && (arg->pos == 0))
+ {
+ p_dir->prop.dir.pos.index = fnt_entry.index;
+ p_dir->prop.dir.pos.pos = p_arc->fnt + fnt_entry.start;
+ }
+ p_dir->prop.dir.parent = (u32) (fnt_entry.parent & BIT_MASK(12));
+ }
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_ReadDirCommand(FSFile *p_dir)
+{
+ FSDirEntry *p_entry = p_dir->arg.readdir.p_entry;
+ FSResult ret;
+
+ FSiSyncReadParam param;
+ param.arc = p_dir->arc;
+ param.pos = p_dir->prop.dir.pos.pos;
+
+ {
+ u8 len;
+ ret = FSi_ReadTable(&param, &len, sizeof(len));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_entry->name_len = (u32)(len & BIT_MASK(7));
+ p_entry->is_directory = (u32)((len >> 7) & 1);
+ }
+ if (p_entry->name_len == 0)
+ return FS_RESULT_FAILURE;
+
+ if (!p_dir->arg.readdir.skip_string)
+ {
+ ret = FSi_ReadTable(&param, p_entry->name, p_entry->name_len);
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ MI_WriteByte((u8 *)p_entry->name + p_entry->name_len, (u8)'\0');
+ }
+ else
+ {
+ param.pos += p_entry->name_len;
+ }
+
+ if (p_entry->is_directory)
+ {
+ u16 id;
+ ret = FSi_ReadTable(&param, &id, sizeof(id));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_entry->dir_id.arc = p_dir->arc;
+ p_entry->dir_id.own_id = (u16)(id & BIT_MASK(12));
+ p_entry->dir_id.index = 0;
+ p_entry->dir_id.pos = 0;
+ }
+ else
+ {
+ p_entry->file_id.arc = p_dir->arc;
+ p_entry->file_id.file_id = p_dir->prop.dir.pos.index;
+ ++p_dir->prop.dir.pos.index;
+ }
+ p_dir->prop.dir.pos.pos = param.pos;
+
+ return ret;
+}
+
+ARM_FUNC FSResult FSi_FindPathCommand(FSFile *p_dir)
+{
+ const char *path = p_dir->arg.findpath.path;
+ const BOOL is_dir = p_dir->arg.findpath.find_directory;
+ p_dir->arg.seekdir.pos = p_dir->arg.findpath.pos;
+ (void)FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+ for (; MI_ReadByte(path); path += (MI_ReadByte(path) ? 1 : 0))
+ {
+ u32 is_directory;
+ int name_len = 0;
+ while ((is_directory = MI_ReadByte(path + name_len)),
+ (is_directory && !FSi_IsSlash(is_directory)))
+ ++name_len;
+ if (is_directory || is_dir)
+ is_directory = 1;
+ if (name_len == 0)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else if (MI_ReadByte(path) == '.')
+ {
+ if (name_len == 1)
+ {
+ path += 1;
+ continue;
+ }
+ else if ((name_len == 2) & (MI_ReadByte(path + 1) == '.'))
+ {
+ if (p_dir->prop.dir.pos.own_id != 0)
+ FSi_SeekDirDirect(p_dir, p_dir->prop.dir.parent);
+ path += 2;
+ continue;
+ }
+ }
+ if (name_len > FS_FILE_NAME_MAX)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else
+ {
+ FSDirEntry etr;
+ p_dir->arg.readdir.p_entry = &etr;
+ p_dir->arg.readdir.skip_string = FALSE;
+ for (;;)
+ {
+ if (FSi_TranslateCommand(p_dir, FS_COMMAND_READDIR) != FS_RESULT_SUCCESS)
+ return FS_RESULT_FAILURE;
+ if ((is_directory != etr.is_directory) ||
+ (name_len != etr.name_len) || FSi_StrNICmp(path, etr.name, (u32)name_len))
+ continue;
+ if (is_directory)
+ {
+ path += name_len;
+ p_dir->arg.seekdir.pos = etr.dir_id;
+ (void)FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
+ break;
+ }
+ else if (is_dir)
+ {
+ return FS_RESULT_FAILURE;
+ }
+ else
+ {
+ *p_dir->arg.findpath.result.file = etr.file_id;
+ return FS_RESULT_SUCCESS;
+ }
+ }
+ }
+ }
+ if (!is_dir)
+ return FS_RESULT_FAILURE;
+ *p_dir->arg.findpath.result.dir = p_dir->prop.dir.pos;
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_GetPathCommand(FSFile *p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+
+ FSGetPathInfo *p_info = &p_file->arg.getpath;
+
+ FSDirEntry entry;
+ FSFile tmp;
+ u32 dir_id;
+ u32 file_id;
+ u32 id;
+ u32 len;
+
+ enum
+ { INVALID_ID = 0x10000 };
+
+ FS_InitFile(&tmp);
+ tmp.arc = p_file->arc;
+
+ if (FS_IsDir(p_file))
+ {
+ dir_id = p_file->prop.dir.pos.own_id;
+ file_id = INVALID_ID;
+ }
+ else
+ {
+ file_id = p_file->prop.file.own_id;
+ if (p_info->total_len != 0)
+ {
+ dir_id = p_info->dir_id;
+ }
+ else
+ {
+ u32 pos = 0;
+ u32 num_dir = 0;
+ dir_id = INVALID_ID;
+ do
+ {
+ FSi_SeekDirDirect(&tmp, pos);
+ if (!pos)
+ num_dir = tmp.prop.dir.parent;
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = TRUE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (!entry.is_directory && (entry.file_id.file_id == file_id))
+ {
+ dir_id = tmp.prop.dir.pos.own_id;
+ break;
+ }
+ }
+ }
+ while ((dir_id == INVALID_ID) && (++pos < num_dir));
+ }
+ }
+ if (dir_id == INVALID_ID)
+ {
+ p_info->total_len = 0;
+ return FS_RESULT_FAILURE;
+ }
+ if (p_info->total_len == 0)
+ {
+ len = 0;
+ if (p_arc->name.pack <= 0x000000FF)
+ len += 1;
+ else if (p_arc->name.pack <= 0x0000FF00)
+ len += 2;
+ else
+ len += 3;
+ len += 1 + 1;
+ if (file_id != INVALID_ID)
+ len += entry.name_len;
+ id = dir_id;
+ if (id != 0)
+ {
+ FSi_SeekDirDirect(&tmp, id);
+ do
+ {
+ FSi_SeekDirDirect(&tmp, tmp.prop.dir.parent);
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = TRUE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (entry.is_directory && (entry.dir_id.own_id == id))
+ {
+ len += entry.name_len + 1;
+ break;
+ }
+ }
+ id = tmp.prop.dir.pos.own_id;
+ }
+ while (id != 0);
+ }
+ p_info->total_len = (u16)(len + 1);
+ p_info->dir_id = (u16)dir_id;
+ }
+ if (!p_info->buf)
+ return FS_RESULT_SUCCESS;
+ if (p_info->buf_len < p_info->total_len)
+ return FS_RESULT_FAILURE;
+ else
+ {
+ u8 *dst = p_info->buf;
+ u32 total = p_info->total_len;
+ u32 pos = 0;
+ if (p_arc->name.pack <= 0x000000FF)
+ len = 1;
+ else if (p_arc->name.pack <= 0x0000FF00)
+ len = 2;
+ else
+ len = 3;
+ MI_CpuCopy8(p_arc->name.ptr, dst + pos, len);
+ pos += len;
+ MI_CpuCopy8(":/", dst + pos, 2);
+ pos += 2;
+ id = dir_id;
+ FSi_SeekDirDirect(&tmp, id);
+ if (file_id != INVALID_ID)
+ {
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = FALSE;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (!entry.is_directory && (entry.file_id.file_id == file_id))
+ break;
+ }
+ len = entry.name_len + 1;
+ MI_CpuCopy8(entry.name, dst + total - len, len);
+ total -= len;
+ }
+ else
+ {
+ MI_WriteByte(dst + total - 1, '\0');
+ total -= 1;
+ }
+ if (id != 0)
+ {
+ do
+ {
+ FSi_SeekDirDirect(&tmp, tmp.prop.dir.parent);
+ tmp.arg.readdir.p_entry = &entry;
+ tmp.arg.readdir.skip_string = FALSE;
+ MI_WriteByte(dst + total - 1, '/');
+ total -= 1;
+ while (FSi_TranslateCommand(&tmp, FS_COMMAND_READDIR) == FS_RESULT_SUCCESS)
+ {
+ if (entry.is_directory && (entry.dir_id.own_id == id))
+ {
+ len = entry.name_len;
+ MI_CpuCopy8(entry.name, dst + total - len, len);
+ total -= len;
+ break;
+ }
+ }
+ id = tmp.prop.dir.pos.own_id;
+ }
+ while (id != 0);
+ }
+ }
+
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_OpenFileFastCommand(FSFile * p_file)
+{
+ FSArchive *const p_arc = p_file->arc;
+ const FSFileID *p_id = &p_file->arg.openfilefast.id;
+ const u32 index = p_id->file_id;
+ FSResult ret;
+
+ {
+ u32 pos = (u32)(index * sizeof(FSArchiveFAT));
+ if (pos >= p_arc->fat_size)
+ return FS_RESULT_FAILURE;
+ else
+ {
+ FSArchiveFAT fat;
+ FSiSyncReadParam param;
+ param.arc = p_arc;
+ param.pos = p_arc->fat + pos;
+ ret = FSi_ReadTable(&param, &fat, sizeof(fat));
+ if (ret != FS_RESULT_SUCCESS)
+ return ret;
+ p_file->arg.openfiledirect.top = fat.top;
+ p_file->arg.openfiledirect.bottom = fat.bottom;
+ p_file->arg.openfiledirect.index = index;
+ return FSi_TranslateCommand(p_file, FS_COMMAND_OPENFILEDIRECT);
+ }
+ }
+}
+
+ARM_FUNC FSResult FSi_OpenFileDirectCommand(FSFile * p_file)
+{
+ p_file->prop.file.top = p_file->arg.openfiledirect.top;
+ p_file->prop.file.pos = p_file->arg.openfiledirect.top;
+ p_file->prop.file.bottom = p_file->arg.openfiledirect.bottom;
+ p_file->prop.file.own_id = p_file->arg.openfiledirect.index;
+ return FS_RESULT_SUCCESS;
+}
+
+ARM_FUNC FSResult FSi_CloseFileCommand(FSFile * p_file)
+{
+ return FS_RESULT_SUCCESS;
+}
diff --git a/arm9/lib/src/FS_file.c b/arm9/lib/src/FS_file.c
new file mode 100644
index 00000000..8bca5c8e
--- /dev/null
+++ b/arm9/lib/src/FS_file.c
@@ -0,0 +1,242 @@
+#include "nitro.h"
+#include "MI_byteAccess.h"
+#include "FS_rom.h"
+#include "FS_file.h"
+#include "FSi_util.h"
+
+extern FSDirPos current_dir_pos;
+BOOL is_init = FALSE;
+
+ARM_FUNC void FS_Init(u32 default_dma_no)
+{
+ if (!is_init)
+ {
+ is_init = TRUE;
+ FSi_InitRom(default_dma_no);
+ }
+}
+
+ARM_FUNC BOOL FS_IsAvailable(void)
+{
+ return is_init;
+}
+
+ARM_FUNC void FS_InitFile(FSFile * p_file)
+{
+ p_file->link.next = p_file->link.prev = NULL;
+ OS_InitThreadQueue(p_file->queue);
+ p_file->arc = NULL;
+ p_file->command = FS_COMMAND_INVALID;
+ p_file->stat = 0;
+}
+
+static BOOL FSi_FindPath(FSFile * p_dir, const char * path, FSFileID * p_file_id, FSDirPos * p_dir_pos)
+{
+ FSDirPos pos;
+ if (FSi_IsSlash(MI_ReadByte(path)))
+ {
+ pos.arc = current_dir_pos.arc;
+ pos.own_id = 0;
+ pos.pos = 0;
+ pos.index = 0;
+ path++;
+ }
+ else
+ {
+ int i;
+ pos = current_dir_pos;
+ for (i = 0; i <= FS_ARCHIVE_NAME_LEN_MAX; ++i)
+ {
+ u32 c = MI_ReadByte(path + i);
+ if (!c || FSi_IsSlash(c))
+ break;
+ else if (c == ':')
+ {
+ FSArchive * const p_arc = FS_FindArchive(path, i);
+ if (!p_arc)
+ {
+ return FALSE;
+ }
+ else if (!FS_IsArchiveLoaded(p_arc))
+ {
+ return FALSE;
+ }
+ pos.arc = p_arc;
+ pos.pos = 0;
+ pos.index = 0;
+ pos.own_id = 0;
+ path += i + 1;
+ if (FSi_IsSlash(MI_ReadByte(path)))
+ ++path;
+ break;
+ }
+ }
+ }
+ p_dir->arc = pos.arc;
+ p_dir->arg.findpath.path = path;
+ p_dir->arg.findpath.pos = pos;
+ if (p_dir_pos)
+ {
+ p_dir->arg.findpath.find_directory = TRUE;
+ p_dir->arg.findpath.result.dir = p_dir_pos;
+ }
+ else
+ {
+ p_dir->arg.findpath.find_directory = FALSE;
+ p_dir->arg.findpath.result.file = p_file_id;
+ }
+ return FSi_SendCommand(p_dir, FS_COMMAND_FINDPATH);
+}
+
+ARM_FUNC int FSi_ReadFileCore(FSFile * p_file, void * dst, s32 len, BOOL async)
+{
+ const s32 pos = p_file->prop.file.pos;
+ const s32 rest = p_file->prop.file.bottom - pos;
+ const u32 org = len;
+ if (len > rest)
+ len = rest;
+ if (len < 0)
+ len = 0;
+ p_file->arg.readfile.dst = dst;
+ p_file->arg.readfile.len_org = org;
+ p_file->arg.readfile.len = len;
+ if (!async)
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ FSi_SendCommand(p_file, FS_COMMAND_READFILE);
+ if (!async)
+ {
+ if (FS_WaitAsync(p_file))
+ len = p_file->prop.file.pos - pos;
+ else
+ len = -1;
+ }
+ return len;
+}
+
+ARM_FUNC BOOL FS_ConvertPathToFileID(FSFileID * p_file_id, const char * path)
+{
+ FSFile dir;
+ FS_InitFile(&dir);
+ if (!FSi_FindPath(&dir, path, p_file_id, NULL))
+ return FALSE;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFileDirect(FSFile * p_file, FSArchive * p_arc, u32 image_top, u32 image_bottom, u32 file_index)
+{
+ p_file->arc = p_arc;
+ p_file->arg.openfiledirect.index = file_index;
+ p_file->arg.openfiledirect.top = image_top;
+ p_file->arg.openfiledirect.bottom = image_bottom;
+ if (!FSi_SendCommand(p_file, FS_COMMAND_OPENFILEDIRECT))
+ return FALSE;
+ p_file->stat |= FS_FILE_STATUS_IS_FILE;
+ p_file->stat &= ~FS_FILE_STATUS_IS_DIR;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFileFast(FSFile * p_file, FSFileID file_id)
+{
+ if (!file_id.arc)
+ return FALSE;
+ p_file->arc = file_id.arc;
+ p_file->arg.openfilefast.id = file_id;
+ if (!FSi_SendCommand(p_file, FS_COMMAND_OPENFILEFAST))
+ return FALSE;
+ p_file->stat |= FS_FILE_STATUS_IS_FILE;
+ p_file->stat &= ~FS_FILE_STATUS_IS_DIR;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_OpenFile(FSFile * p_file, const char * path)
+{
+ FSFileID file_id;
+ return FS_ConvertPathToFileID(&file_id, path) && FS_OpenFileFast(p_file, file_id);
+}
+
+ARM_FUNC BOOL FS_CloseFile(FSFile * p_file)
+{
+ if (!FSi_SendCommand(p_file, FS_COMMAND_CLOSEFILE))
+ return FALSE;
+ p_file->arc = NULL;
+ p_file->command = FS_COMMAND_INVALID;
+ p_file->stat &= ~(FS_FILE_STATUS_IS_FILE | FS_FILE_STATUS_IS_DIR);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_WaitAsync(FSFile * p_file)
+{
+ BOOL is_owner = FALSE;
+ OSIntrMode bak_par = OS_DisableInterrupts();
+ if (FS_IsBusy(p_file))
+ {
+ is_owner = !(p_file->stat & (FS_FILE_STATUS_SYNC | FS_FILE_STATUS_OPERATING));
+ if (is_owner)
+ {
+ p_file->stat |= FS_FILE_STATUS_SYNC;
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (!(p_file->stat & FS_FILE_STATUS_OPERATING));
+ }
+ else
+ {
+ do
+ {
+ OS_SleepThread(p_file->queue);
+ } while (FS_IsBusy(p_file));
+ }
+ }
+ (void)OS_RestoreInterrupts(bak_par);
+ if (is_owner)
+ {
+ return FSi_ExecuteSyncCommand(p_file);
+ }
+
+ return FS_IsSucceeded(p_file);
+}
+
+ARM_FUNC int FS_ReadFileAsync(FSFile * p_file, void * dst, s32 len)
+{
+ return FSi_ReadFileCore(p_file, dst, len, TRUE);
+}
+
+ARM_FUNC int FS_ReadFile(FSFile * p_file, void * dst, s32 len)
+{
+ return FSi_ReadFileCore(p_file, dst, len, FALSE);
+}
+
+ARM_FUNC BOOL FS_SeekFile(FSFile * p_file, int offset, FSSeekFileMode origin)
+{
+ switch (origin)
+ {
+ case FS_SEEK_SET:
+ offset += p_file->prop.file.top;
+ break;
+ case FS_SEEK_CUR:
+ offset += p_file->prop.file.pos;
+ break;
+ case FS_SEEK_END:
+ offset += p_file->prop.file.bottom;
+ break;
+ default:
+ return FALSE;
+ }
+ if (offset < (s32)p_file->prop.file.top)
+ offset = (s32)p_file->prop.file.top;
+ if (offset > (s32)p_file->prop.file.bottom)
+ offset = (s32)p_file->prop.file.bottom;
+ p_file->prop.file.pos = offset;
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_ChangeDir(const char * path)
+{
+ FSDirPos pos;
+ FSFile dir;
+ FS_InitFile(&dir);
+ if (!FSi_FindPath(&dir, path, NULL, &pos))
+ return FALSE;
+ current_dir_pos = pos;
+ return TRUE;
+}
diff --git a/arm9/lib/src/FS_overlay.c b/arm9/lib/src/FS_overlay.c
new file mode 100644
index 00000000..79a3b43e
--- /dev/null
+++ b/arm9/lib/src/FS_overlay.c
@@ -0,0 +1,320 @@
+#include "nitro.h"
+#include "DGT_common.h"
+#include "DGT_dgt.h"
+#include "OS_cache.h"
+#include "OS_system.h"
+#include "OS_printf.h"
+#include "MI_memory.h"
+#include "MI_uncompress.h"
+#include "FS_rom.h"
+#include "FS_overlay.h"
+#include "FS_mw_dtor.h"
+#include "MB_mb.h"
+
+#define FS_OVERLAY_FLAG_COMP 0x0001
+#define FS_OVERLAY_FLAG_AUTH 0x0002
+#define FS_OVERLAY_DIGEST_SIZE DGT_HASH2_DIGEST_SIZE
+
+ARM_FUNC u32 FSi_GetOverlayBinarySize(FSOverlayInfo * p_ovi)
+{
+ u32 size = (p_ovi->header.flag & FS_OVERLAY_FLAG_COMP)
+ ? p_ovi->header.compressed
+ : p_ovi->header.ram_size;
+ return size;
+}
+
+ARM_FUNC void FS_ClearOverlayImage(FSOverlayInfo * p_ovi)
+{
+ u8 * const im_start = FS_GetOverlayAddress(p_ovi);
+ u32 const ram_size = FS_GetOverlayImageSize(p_ovi);
+ u32 const total_size = FS_GetOverlayTotalSize(p_ovi);
+
+ IC_InvalidateRange(im_start, total_size);
+ DC_InvalidateRange(im_start, total_size);
+ MI_CpuFill8(im_start + ram_size, 0, total_size - ram_size);
+}
+
+ARM_FUNC FSFileID FS_GetOverlayFileID(FSOverlayInfo * p_ovi)
+{
+ FSFileID ret;
+ ret.arc = &fsi_arc_rom;
+ ret.file_id = p_ovi->header.file_id;
+ return ret;
+}
+
+ARM_FUNC BOOL FSi_LoadOverlayInfoCore(FSOverlayInfo * p_ovi, MIProcessor target, FSOverlayID id, FSArchive * arc, u32 offset_arm9, u32 len_arm9, u32 offset_arm7, u32 len_arm7)
+{
+ CARDRomRegion pr[1];
+ u32 pos;
+ if (target == MI_PROCESSOR_ARM9)
+ {
+ pr->offset = offset_arm9;
+ pr->length = len_arm9;
+ }
+ else
+ {
+ pr->offset = offset_arm7;
+ pr->length = len_arm7;
+ }
+ pos = (u32) id * sizeof(FSOverlayInfoHeader);
+ if (pos >= pr->length)
+ return FALSE;
+
+ FSFile file[1];
+ FS_InitFile(file);
+ // BOOL FS_OpenFileDirect(FSFile * p_file, FSArchive * p_arc, u32 image_top, u32 image_bottom, u32 file_index)
+ if (!FS_OpenFileDirect(file, arc, pr->offset + pos, pr->offset + pr->length, (u32)~0))
+ return FALSE;
+ if (FS_ReadFile(file, p_ovi, sizeof(FSOverlayInfoHeader)) != sizeof(FSOverlayInfoHeader))
+ {
+ FS_CloseFile(file);
+ return FALSE;
+ }
+ FS_CloseFile(file);
+ p_ovi->target = target;
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ p_ovi->file_pos.offset = FS_GetFileImageTop(file);
+ p_ovi->file_pos.length = FS_GetLength(file);
+ FS_CloseFile(file);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_LoadOverlayInfo(FSOverlayInfo * p_ovi, MIProcessor target, FSOverlayID id)
+{
+ CARDRomRegion * const pr = (target == MI_PROCESSOR_ARM9) ? &fsi_ovt9 : &fsi_ovt7;
+ if (pr->offset)
+ {
+ FSFile file[1];
+ const u32 pos = id * sizeof(FSOverlayInfoHeader);
+ if (pos >= pr->length)
+ return FALSE;
+ MI_CpuCopy8((const void *)(pr->offset + pos), p_ovi, sizeof(FSOverlayInfoHeader));
+ p_ovi->target = target;
+ FS_InitFile(file);
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ p_ovi->file_pos.offset = FS_GetFileImageTop(file);
+ p_ovi->file_pos.length = FS_GetLength(file);
+ FS_CloseFile(file);
+ return TRUE;
+ }
+ else
+ {
+ const CARDRomRegion * const p_ovt9 = CARD_GetRomRegionOVT(MI_PROCESSOR_ARM9);
+ const CARDRomRegion * const p_ovt7 = CARD_GetRomRegionOVT(MI_PROCESSOR_ARM7);
+ return FSi_LoadOverlayInfoCore(p_ovi, target, id, &fsi_arc_rom, p_ovt9->offset, p_ovt9->length, p_ovt7->offset, p_ovt7->length);
+ }
+}
+
+ARM_FUNC BOOL FS_LoadOverlayImageAsync(FSOverlayInfo * p_ovi, FSFile * p_file)
+{
+ FS_InitFile(p_file);
+ if (!FS_OpenFileFast(p_file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ else
+ {
+ s32 size = FSi_GetOverlayBinarySize(p_ovi);
+ FS_ClearOverlayImage(p_ovi);
+ if (FS_ReadFileAsync(p_file, FS_GetOverlayAddress(p_ovi), size) != size)
+ {
+ FS_CloseFile(p_file);
+ return FALSE;
+ }
+ return TRUE;
+ }
+}
+
+ARM_FUNC BOOL FS_LoadOverlayImage(FSOverlayInfo * p_ovi)
+{
+ FSFile file[1];
+ FS_InitFile(file);
+ if (!FS_OpenFileFast(file, FS_GetOverlayFileID(p_ovi)))
+ return FALSE;
+ else
+ {
+ s32 size = FSi_GetOverlayBinarySize(p_ovi);
+ FS_ClearOverlayImage(p_ovi);
+ if (FS_ReadFile(file, FS_GetOverlayAddress(p_ovi), size) != size)
+ {
+ FS_CloseFile(file);
+ return FALSE;
+ }
+ FS_CloseFile(file);
+ return TRUE;
+ }
+}
+
+static const u8 fsi_def_digest_key[64] = {
+ 0x21, 0x06, 0xc0, 0xde,
+ 0xba, 0x98, 0xce, 0x3f,
+ 0xa6, 0x92, 0xe3, 0x9d,
+ 0x46, 0xf2, 0xed, 0x01,
+
+ 0x76, 0xe3, 0xcc, 0x08,
+ 0x56, 0x23, 0x63, 0xfa,
+ 0xca, 0xd4, 0xec, 0xdf,
+ 0x9a, 0x62, 0x78, 0x34,
+
+ 0x8f, 0x6d, 0x63, 0x3c,
+ 0xfe, 0x22, 0xca, 0x92,
+ 0x20, 0x88, 0x97, 0x23,
+ 0xd2, 0xcf, 0xae, 0xc2,
+
+ 0x32, 0x67, 0x8d, 0xfe,
+ 0xca, 0x83, 0x64, 0x98,
+ 0xac, 0xfd, 0x3e, 0x37,
+ 0x87, 0x46, 0x58, 0x24,
+};
+
+static const void *fsi_digest_key_ptr = fsi_def_digest_key;
+static int fsi_digest_key_len = sizeof(fsi_def_digest_key);
+
+ARM_FUNC BOOL FSi_CompareDigest(const u8 *spec_digest, void *src, int len)
+{
+ int i;
+ u8 digest[FS_OVERLAY_DIGEST_SIZE];
+ u8 digest_key[64];
+
+ MI_CpuClear8(digest, sizeof(digest));
+ MI_CpuCopy8(fsi_digest_key_ptr, digest_key, fsi_digest_key_len);
+ DGT_Hash2CalcHmac(digest, src, len, digest_key, fsi_digest_key_len);
+ for (i = 0; i < sizeof(digest); i += sizeof(u32))
+ {
+ if (*(const u32 *)(digest + i) != *(const u32 *)(spec_digest + i))
+ break;
+ }
+ return i == sizeof(digest);
+}
+
+extern u8 SDK_OVERLAY_DIGEST[];
+extern u8 SDK_OVERLAY_DIGEST_END[];
+
+ARM_FUNC void FS_StartOverlay(FSOverlayInfo * p_ovi)
+{
+ u32 rare_size = FSi_GetOverlayBinarySize(p_ovi);
+ if (MB_IsMultiBootChild())
+ {
+ BOOL ret = FALSE;
+
+ if (p_ovi->header.flag & FS_OVERLAY_FLAG_AUTH)
+ {
+ const u32 odt_max = (u32)((SDK_OVERLAY_DIGEST_END - SDK_OVERLAY_DIGEST) / FS_OVERLAY_DIGEST_SIZE);
+ if (p_ovi->header.id < odt_max)
+ {
+ const u8 * spec_digest = SDK_OVERLAY_DIGEST + FS_OVERLAY_DIGEST_SIZE * p_ovi->header.id;
+ ret = FSi_CompareDigest(spec_digest, p_ovi->header.ram_address, (int)rare_size);
+ }
+ }
+ if (!ret)
+ {
+ MI_CpuClear8(p_ovi->header.ram_address, rare_size);
+ OS_TPanic("FS_StartOverlay() failed! (invalid overlay-segment data)");
+ return;
+ }
+ }
+ if (p_ovi->header.flag & FS_OVERLAY_FLAG_COMP)
+ {
+ MIi_UncompressBackward(p_ovi->header.ram_address + rare_size);
+ }
+ DC_FlushRange(p_ovi->header.ram_address, p_ovi->header.ram_size);
+
+ {
+ FSOverlayInitFunc *p = p_ovi->header.sinit_init;
+ FSOverlayInitFunc *q = p_ovi->header.sinit_init_end;
+ for (; p < q; ++p)
+ {
+ if (*p)
+ (**p)();
+ }
+ }
+}
+
+ARM_FUNC void FS_EndOverlay(FSOverlayInfo *p_ovi)
+{
+ for (;;)
+ {
+ MWiDestructorChain *head = NULL, *tail = NULL;
+ const u32 region_top = (u32)FS_GetOverlayAddress(p_ovi);
+ const u32 region_bottom = region_top + FS_GetOverlayTotalSize(p_ovi);
+
+ {
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ MWiDestructorChain *prev = NULL;
+ MWiDestructorChain *base = __global_destructor_chain;
+ MWiDestructorChain *p = base;
+ while (p)
+ {
+ MWiDestructorChain *next = p->next;
+ const u32 dtor = (u32)p->dtor;
+ const u32 obj = (u32)p->obj;
+ if (((obj == 0) && (dtor >= region_top) && (dtor < region_bottom)) ||
+ ((obj >= region_top) && (obj < region_bottom)))
+ {
+ /* If appropriate, extract*/
+ if (!tail)
+ {
+ head = p;
+ }
+ else
+ {
+ tail->next = p;
+ }
+ if (base == p)
+ {
+ base = __global_destructor_chain = next;
+ }
+ tail = p, p->next = NULL;
+ if (prev)
+ {
+ prev->next = next;
+ }
+ }
+ else
+ {
+ prev = p;
+ }
+ p = next;
+ }
+ OS_RestoreInterrupts(bak_psr);
+ }
+
+ if (!head)
+ {
+ break;
+ }
+ do
+ {
+ MWiDestructorChain *next = head->next;
+ if (head->dtor)
+ {
+ (*head->dtor) (head->obj);
+ }
+ head = next;
+ }
+ while (head);
+ }
+}
+
+ARM_FUNC BOOL FS_UnloadOverlayImage(FSOverlayInfo * p_ovi)
+{
+ FS_EndOverlay(p_ovi);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_LoadOverlay(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo ovi;
+ if (!FS_LoadOverlayInfo(&ovi, target, id) || !FS_LoadOverlayImage(&ovi))
+ return FALSE;
+ FS_StartOverlay(&ovi);
+ return TRUE;
+}
+
+ARM_FUNC BOOL FS_UnloadOverlay(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo ovi;
+ if (!FS_LoadOverlayInfo(&ovi, target, id) || !FS_UnloadOverlayImage(&ovi))
+ return FALSE;
+ return TRUE;
+}
diff --git a/arm9/lib/src/FS_rom.c b/arm9/lib/src/FS_rom.c
new file mode 100644
index 00000000..32f66c10
--- /dev/null
+++ b/arm9/lib/src/FS_rom.c
@@ -0,0 +1,118 @@
+#include "FS_rom.h"
+#include "FS_archive.h"
+#include "FS_file.h"
+#include "CARD_pullOut.h"
+#include "CARD_rom.h"
+#include "CARD_common.h"
+#include "MB_mb.h"
+#include "OS_printf.h"
+
+u32 fsi_default_dma_no;
+
+ARM_FUNC void FSi_OnRomReadDone(void * p_arc)
+{
+ FS_NotifyArchiveAsyncEnd(p_arc, CARD_IsPulledOut() ? FS_RESULT_ERROR : FS_RESULT_SUCCESS);
+}
+
+ARM_FUNC FSResult FSi_ReadRomCallback(FSArchive * p_arc, void * dst, u32 src, u32 len)
+{
+ CARD_ReadRomAsync(fsi_default_dma_no, (const void *)src, dst, len, FSi_OnRomReadDone, p_arc);
+ return FS_RESULT_PROC_ASYNC;
+}
+
+ARM_FUNC FSResult FSi_WriteDummyCallback(FSArchive * p_arc, const void *src, u32 dst, u32 len)
+{
+ return FS_RESULT_FAILURE;
+}
+
+ARM_FUNC FSResult FSi_RomArchiveProc(FSFile * p_arc, FSCommandType cmd)
+{
+ switch (cmd)
+ {
+ case FS_COMMAND_ACTIVATE:
+ CARD_LockRom(fsi_card_lock_id);
+ return FS_RESULT_SUCCESS;
+ case FS_COMMAND_IDLE:
+ CARD_UnlockRom(fsi_card_lock_id);
+ return FS_RESULT_SUCCESS;
+ case FS_COMMAND_WRITEFILE:
+ return FS_RESULT_UNSUPPORTED;
+ default:
+ return FS_RESULT_PROC_UNKNOWN;
+ }
+}
+
+ARM_FUNC FSResult FSi_ReadDummyCallback(FSArchive *p_arc, void *dst, u32 src, u32 len)
+{
+ return FS_RESULT_FAILURE;
+}
+
+ARM_FUNC FSResult FSi_EmptyArchiveProc(FSFile *p_file, FSCommandType cmd)
+{
+ return FS_RESULT_UNSUPPORTED;
+}
+
+ARM_FUNC void FSi_InitRom(u32 default_dma_no)
+{
+ fsi_default_dma_no = default_dma_no;
+ fsi_card_lock_id = OS_GetLockID();
+ fsi_ovt9.offset = 0;
+ fsi_ovt9.length = 0;
+ fsi_ovt7.offset = 0;
+ fsi_ovt7.length = 0;
+
+ CARD_Init();
+
+ FS_InitArchive(&fsi_arc_rom);
+ FS_RegisterArchiveName(&fsi_arc_rom, "rom", 3);
+
+ if (MB_IsMultiBootChild())
+ {
+ fsi_ovt9.offset = (u32)~0;
+ fsi_ovt9.length = 0;
+ fsi_ovt7.offset = (u32)~0;
+ fsi_ovt7.length = 0;
+ FS_SetArchiveProc(&fsi_arc_rom, FSi_EmptyArchiveProc, (u32)FS_ARCHIVE_PROC_ALL);
+ FS_LoadArchive(&fsi_arc_rom, 0x00000000, 0, 0, 0, 0, FSi_ReadDummyCallback, FSi_WriteDummyCallback);
+ }
+ else
+ {
+ const CARDRomRegion *const fnt = CARD_GetRomRegionFNT();
+ const CARDRomRegion *const fat = CARD_GetRomRegionFAT();
+
+ FS_SetArchiveProc(&fsi_arc_rom, FSi_RomArchiveProc,
+ FS_ARCHIVE_PROC_WRITEFILE |
+ FS_ARCHIVE_PROC_ACTIVATE | FS_ARCHIVE_PROC_IDLE);
+
+ if ((fnt->offset == 0xFFFFFFFF) || (fnt->offset == 0x00000000) ||
+ (fat->offset == 0xFFFFFFFF) || (fat->offset == 0x00000000))
+ {
+ OS_Warning("file-system : no MAKEROM-information in rom header.");
+ }
+ else
+ {
+ FS_LoadArchive(&fsi_arc_rom, 0x00000000,
+ fat->offset, fat->length,
+ fnt->offset, fnt->length,
+ FSi_ReadRomCallback, FSi_WriteDummyCallback);
+ }
+ }
+}
+
+ARM_FUNC u32 FS_SetDefaultDMA(u32 dma_no)
+{
+ OSIntrMode bak_psr = OS_DisableInterrupts();
+ u32 bak_dma_no = fsi_default_dma_no;
+ BOOL bak_stat = FS_SuspendArchive(&fsi_arc_rom);
+ fsi_default_dma_no = dma_no;
+ if (bak_stat)
+ FS_ResumeArchive(&fsi_arc_rom);
+ OS_RestoreInterrupts(bak_psr);
+ return bak_dma_no;
+}
+
+ARM_FUNC u32 FS_TryLoadTable(void * p_mem, u32 size)
+{
+ return FS_LoadArchiveTables(&fsi_arc_rom, p_mem, size);
+}
+
diff --git a/arm9/lib/src/OS_reset.c b/arm9/lib/src/OS_reset.c
index 28d815a9..c21d20ab 100644
--- a/arm9/lib/src/OS_reset.c
+++ b/arm9/lib/src/OS_reset.c
@@ -14,7 +14,6 @@ extern u32 PXI_IsCallbackReady(u32 param1, u32 param2);
extern void PXI_SetFifoRecvCallback(u32 param1, void* callback);
extern u32 PXI_SendWordByFifo(u32 param1, u32 data, u32 param2);
extern void CARD_LockRom(u16 lockId);
-extern u32 OS_GetLockID();
extern void MI_StopDma(u32 dma);
extern void OS_SetIrqMask(u32 mask);
extern void OS_ResetRequestIrqMask(u32 mask);
diff --git a/arm9/modules/13/asm/module_13_arm2.s b/arm9/modules/13/asm/module_13_arm2.s
index 028a3b7c..7910e1a0 100644
--- a/arm9/modules/13/asm/module_13_arm2.s
+++ b/arm9/modules/13/asm/module_13_arm2.s
@@ -31909,11 +31909,11 @@ MOD13_022395A0: ; 0x022395A0
ldr r0, _02239628 ; =0x02243190
ldr r0, [r0]
add r0, r0, #0x88
- bl FUN_020D0EB0
+ bl FS_UnloadArchive
ldr r0, _02239628 ; =0x02243190
ldr r0, [r0]
add r0, r0, #0x88
- bl FUN_020D0FF0
+ bl FS_ReleaseArchiveName
ldr r0, _02239628 ; =0x02243190
ldr r0, [r0]
ldrh r0, [r0, #0xe4]
@@ -32012,7 +32012,7 @@ _02239738:
ldr r0, [r0]
mov r2, r1
add r0, r0, #0x88
- bl FUN_020D0D84
+ bl FS_LoadArchiveTables
mov r1, #4
mov r4, r0
bl MOD13_0223B004
@@ -32022,7 +32022,7 @@ _02239738:
str r0, [r3]
ldr r0, [r1]
ldr r1, [r0], #0x88
- bl FUN_020D0D84
+ bl FS_LoadArchiveTables
ldr r1, _022397BC ; =0x02243190
mov r0, #0x20
ldr r1, [r1]
diff --git a/arm9/src/poke_overlay.c b/arm9/src/poke_overlay.c
new file mode 100644
index 00000000..105881d8
--- /dev/null
+++ b/arm9/src/poke_overlay.c
@@ -0,0 +1,203 @@
+#include "global.h"
+#include "nitro.h"
+#include "FS_file.h"
+#include "FS_overlay.h"
+
+#define OVERLAY_LOAD_WRAM 0
+#define OVERLAY_LOAD_ITCM 1
+#define OVERLAY_LOAD_DTCM 2
+
+extern void ErrorHandling(void);
+
+struct LoadedOverlay {
+ FSOverlayID id;
+ BOOL active;
+};
+
+extern struct LoadedOverlay gLoadedOverlays[3][8];
+
+struct LoadedOverlay* GetLoadedOverlaysInRegion(int);
+BOOL GetOverlayRamBounds(FSOverlayID, void**, void**);
+BOOL CanOverlayBeLoaded(FSOverlayID);
+int GetOverlayLoadDestination(FSOverlayID);
+BOOL LoadOverlayNormal(MIProcessor, FSOverlayID);
+BOOL LoadOverlayNoInit(MIProcessor, FSOverlayID);
+BOOL LoadOverlayNoInitAsync(MIProcessor, FSOverlayID);
+
+THUMB_FUNC void FreeOverlayAllocation(struct LoadedOverlay * loaded)
+{
+ if (loaded->active != TRUE)
+ ErrorHandling();
+ if (FS_UnloadOverlay(MI_PROCESSOR_ARM9, loaded->id) != TRUE)
+ ErrorHandling();
+ loaded->active = FALSE;
+}
+
+THUMB_FUNC void UnloadOverlayByID(FSOverlayID id)
+{
+ struct LoadedOverlay * loaded = GetLoadedOverlaysInRegion(GetOverlayLoadDestination(id));
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ if (loaded[i].active == TRUE && loaded[i].id == id)
+ {
+ FreeOverlayAllocation(&loaded[i]);
+ break;
+ }
+ }
+}
+
+THUMB_FUNC int GetOverlayLoadDestination(FSOverlayID id)
+{
+ FSOverlayInfo info;
+ u8 *end;
+ u8 *start;
+ if (FS_LoadOverlayInfo(&info, MI_PROCESSOR_ARM9, id) != TRUE)
+ ErrorHandling();
+ start = (u8 *)HW_ITCM_IMAGE;
+ end = (u8 *)HW_ITCM_END;
+ if (info.header.ram_address <= end && info.header.ram_address >= start)
+ return OVERLAY_LOAD_ITCM;
+ start = (u8 *)SDK_AUTOLOAD_DTCM_START;
+ end = start + HW_DTCM_SIZE;
+ if (info.header.ram_address <= end && info.header.ram_address >= start)
+ return OVERLAY_LOAD_DTCM;
+ return OVERLAY_LOAD_WRAM;
+}
+
+THUMB_FUNC BOOL HandleLoadOverlay(FSOverlayID id, int a1)
+{
+ u32 sp0 = FS_DMA_NOT_USE;
+ struct LoadedOverlay *r3;
+ int r7;
+ int r6;
+ BOOL result;
+
+ if (!CanOverlayBeLoaded(id))
+ return FALSE;
+ r7 = GetOverlayLoadDestination(id);
+ r3 = GetLoadedOverlaysInRegion(r7);
+ for (r6 = 0; r6 < 8; r6++)
+ {
+ if (!r3[r6].active)
+ {
+ struct LoadedOverlay * ovly;
+ ovly = &r3[r6];
+ ovly->active = TRUE;
+ ovly->id = id;
+ break;
+ }
+ }
+ if (r6 >= 8)
+ {
+ ErrorHandling();
+ return FALSE;
+ }
+ if (r7 == OVERLAY_LOAD_ITCM || r7 == OVERLAY_LOAD_DTCM)
+ {
+ sp0 = FS_SetDefaultDMA(FS_DMA_NOT_USE);
+ }
+ switch (a1)
+ {
+ case 0:
+ result = LoadOverlayNormal(MI_PROCESSOR_ARM9, id);
+ break;
+ case 1:
+ result = LoadOverlayNoInit(MI_PROCESSOR_ARM9, id);
+ break;
+ case 2:
+ result = LoadOverlayNoInitAsync(MI_PROCESSOR_ARM9, id);
+ break;
+ default:
+ ErrorHandling();
+ return FALSE;
+ }
+ if (r7 == OVERLAY_LOAD_ITCM || r7 == OVERLAY_LOAD_DTCM)
+ {
+ FS_SetDefaultDMA(sp0);
+ }
+ if (result == 0)
+ {
+ ErrorHandling();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+THUMB_FUNC BOOL CanOverlayBeLoaded(FSOverlayID id)
+{
+ void *start, *end, *start2, *end2;
+ struct LoadedOverlay *r5;
+ int i;
+ if (!GetOverlayRamBounds(id, &start, &end))
+ return FALSE;
+ r5 = GetLoadedOverlaysInRegion(GetOverlayLoadDestination(id));
+ for (i = 0; i < 8; i++)
+ {
+ if (r5[i].active == TRUE && GetOverlayRamBounds(r5[i].id, &start2, &end2) == TRUE)
+ {
+ if ((start >= start2 && start < end2) || (end > start2 && end <= end2) || (start <= start2 && end >= end2))
+ {
+ ErrorHandling();
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+THUMB_FUNC struct LoadedOverlay* GetLoadedOverlaysInRegion(int a0)
+{
+ switch (a0)
+ {
+ case OVERLAY_LOAD_WRAM:
+ default:
+ return gLoadedOverlays[0];
+ case OVERLAY_LOAD_ITCM:
+ return gLoadedOverlays[1];
+ case OVERLAY_LOAD_DTCM:
+ return gLoadedOverlays[2];
+ }
+}
+
+THUMB_FUNC BOOL GetOverlayRamBounds(FSOverlayID id, void ** start, void ** end)
+{
+ FSOverlayInfo info;
+ if (!FS_LoadOverlayInfo(&info, MI_PROCESSOR_ARM9, id)) {
+ ErrorHandling();
+ return FALSE;
+ }
+ *start = (void *)info.header.ram_address;
+ *end = (char *)*start + (info.header.ram_size + info.header.bss_size);
+ return TRUE;
+}
+
+THUMB_FUNC BOOL LoadOverlayNormal(MIProcessor target, FSOverlayID id)
+{
+ return FS_LoadOverlay(target, id);
+}
+
+THUMB_FUNC BOOL LoadOverlayNoInit(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo info;
+ if (!FS_LoadOverlayInfo(&info, target, id))
+ return FALSE;
+ if (!FS_LoadOverlayImage(&info))
+ return FALSE;
+ FS_StartOverlay(&info);
+ return TRUE;
+}
+
+THUMB_FUNC BOOL LoadOverlayNoInitAsync(MIProcessor target, FSOverlayID id)
+{
+ FSOverlayInfo info;
+ FSFile file;
+ if (!FS_LoadOverlayInfo(&info, target, id))
+ return FALSE;
+ FS_InitFile(&file);
+ FS_LoadOverlayImageAsync(&info, &file);
+ FS_WaitAsync(&file);
+ FS_CloseFile(&file);
+ FS_StartOverlay(&info);
+ return TRUE;
+}
diff --git a/arm9/src/string_util.c b/arm9/src/string_util.c
index 6c949e88..e6ea85de 100644
--- a/arm9/src/string_util.c
+++ b/arm9/src/string_util.c
@@ -1,6 +1,9 @@
#include "global.h"
-u16 gDigitTable[] = {
+#define EOS 0xFFFF
+#define NON_DIGIT 0xE2
+
+const u16 gDigitTable[] = {
0xA2,
0xA3,
0xA4,
@@ -19,7 +22,7 @@ u16 gDigitTable[] = {
0xB1
};
-s32 gPowersOfTen[] = {
+const s32 gPowersOfTen[] = {
1,
10,
100,
@@ -32,8 +35,6 @@ s32 gPowersOfTen[] = {
1000000000,
};
-static const u16 EOS = 0xFFFF;
-
THUMB_FUNC void StringCopy(u16 *dest, const u16 *src)
{
u16 c = *src;
@@ -129,8 +130,6 @@ enum PrintingMode {
PAD_ZEROES
};
-const u16 NON_DIGIT = 0xE2;
-
THUMB_FUNC u16 *ConvertUIntToDecimalString(u16 *dest, u32 value, enum PrintingMode mode, u32 n)
{
for (u32 x = gPowersOfTen[n - 1]; x != 0; x = x / 10) {
diff --git a/arm9/undefined_syms.txt b/arm9/undefined_syms.txt
index d9d0bd09..b5d30064 100644
--- a/arm9/undefined_syms.txt
+++ b/arm9/undefined_syms.txt
@@ -16,9 +16,11 @@ Unk_02106840 = 0x02106840;
Unk_02106900 = 0x02106900;
Unk_02106A00 = 0x02106A00;
Unk_02106A04 = 0x02106A04;
+// FS
+SDK_OVERLAY_DIGEST = 0x02106F84;
+SDK_OVERLAY_DIGEST_END = 0x02106F84;
// Overlay
-FUN_021D74E0 = 0x021D74E0;
FUN_021D76AC = 0x021D76AC;
gUnk021D76C8 = 0x021D76C8;
FUN_021D77C4 = 0x021D77C4;
diff --git a/global.inc b/global.inc
index 76daa539..8166d7bc 100644
--- a/global.inc
+++ b/global.inc
@@ -2558,7 +2558,7 @@
.extern MTX_ScaleApply22
.extern FUN_020C6034
.extern FUN_020C605C
-.extern FUN_021D74E0
+.extern MOD05_021D74E0
.extern FUN_021D76AC
.extern FUN_021D77C4
.extern FUN_021D7800
diff --git a/tools/scaninc/.gitignore b/tools/scaninc/.gitignore
new file mode 100644
index 00000000..94bfbf98
--- /dev/null
+++ b/tools/scaninc/.gitignore
@@ -0,0 +1 @@
+scaninc
diff --git a/tools/scaninc/LICENSE b/tools/scaninc/LICENSE
new file mode 100644
index 00000000..b66bf81c
--- /dev/null
+++ b/tools/scaninc/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 YamaArashi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/tools/scaninc/Makefile b/tools/scaninc/Makefile
new file mode 100644
index 00000000..1516f159
--- /dev/null
+++ b/tools/scaninc/Makefile
@@ -0,0 +1,18 @@
+CXX = g++
+
+CXXFLAGS = -Wall -Werror -std=c++11 -O2
+
+SRCS = scaninc.cpp c_file.cpp asm_file.cpp source_file.cpp
+
+HEADERS := scaninc.h asm_file.h c_file.h source_file.h
+
+.PHONY: all clean
+
+all: scaninc
+ @:
+
+scaninc: $(SRCS) $(HEADERS)
+ $(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS)
+
+clean:
+ $(RM) scaninc scaninc.exe
diff --git a/tools/scaninc/asm_file.cpp b/tools/scaninc/asm_file.cpp
new file mode 100644
index 00000000..109e604a
--- /dev/null
+++ b/tools/scaninc/asm_file.cpp
@@ -0,0 +1,192 @@
+// Copyright(c) 2015-2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include <cstdio>
+#include <string>
+#include "scaninc.h"
+#include "asm_file.h"
+
+AsmFile::AsmFile(std::string path)
+{
+ m_path = path;
+
+ FILE *fp = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str());
+
+ std::fseek(fp, 0, SEEK_END);
+
+ m_size = std::ftell(fp);
+
+ m_buffer = new char[m_size];
+
+ std::rewind(fp);
+
+ if (std::fread(m_buffer, m_size, 1, fp) != 1)
+ FATAL_ERROR("Failed to read \"%s\".\n", path.c_str());
+
+ std::fclose(fp);
+
+ m_pos = 0;
+ m_lineNum = 1;
+}
+
+AsmFile::~AsmFile()
+{
+ delete[] m_buffer;
+}
+
+IncDirectiveType AsmFile::ReadUntilIncDirective(std::string &path)
+{
+ // At the beginning of each loop iteration, the current file position
+ // should be at the start of a line or at the end of the file.
+ for (;;)
+ {
+ SkipTabsAndSpaces();
+
+ IncDirectiveType incDirectiveType = IncDirectiveType::None;
+
+ char c = PeekChar();
+ if (c == '.' || c == '#')
+ {
+ m_pos++;
+
+ if (MatchIncDirective("incbin", path))
+ incDirectiveType = IncDirectiveType::Incbin;
+ else if (MatchIncDirective("include", path))
+ incDirectiveType = IncDirectiveType::Include;
+ }
+
+ for (;;)
+ {
+ int c = GetChar();
+
+ if (c == -1)
+ return incDirectiveType;
+
+ if (c == ';')
+ {
+ SkipEndOfLineComment();
+ break;
+ }
+ else if (c == '/' && PeekChar() == '*')
+ {
+ m_pos++;
+ SkipMultiLineComment();
+ }
+ else if (c == '"')
+ {
+ SkipString();
+ }
+ else if (c == '\n')
+ {
+ break;
+ }
+ }
+
+ if (incDirectiveType != IncDirectiveType::None)
+ return incDirectiveType;
+ }
+}
+
+std::string AsmFile::ReadPath()
+{
+ int length = 0;
+ int startPos = m_pos;
+
+ for (;;)
+ {
+ int c = GetChar();
+
+ if (c == '"')
+ break;
+
+ if (c == -1)
+ FATAL_INPUT_ERROR("unexpected EOF in include string\n");
+
+ if (c == 0)
+ FATAL_INPUT_ERROR("unexpected NUL character in include string\n");
+
+ if (c == '\n')
+ FATAL_INPUT_ERROR("unexpected end of line character in include string\n");
+
+ // Don't bother allowing any escape sequences.
+ if (c == '\\')
+ FATAL_INPUT_ERROR("unexpected escape in include string\n");
+
+ length++;
+
+ if (length > SCANINC_MAX_PATH)
+ FATAL_INPUT_ERROR("path is too long");
+ }
+
+ return std::string(m_buffer + startPos, length);
+}
+
+void AsmFile::SkipEndOfLineComment()
+{
+ int c;
+
+ do
+ {
+ c = GetChar();
+ } while (c != -1 && c != '\n');
+}
+
+void AsmFile::SkipMultiLineComment()
+{
+ for (;;)
+ {
+ int c = GetChar();
+
+ if (c == '*')
+ {
+ if (PeekChar() == '/')
+ {
+ m_pos++;
+ return;
+ }
+ }
+ else if (c == -1)
+ {
+ return;
+ }
+ }
+}
+
+void AsmFile::SkipString()
+{
+ for (;;)
+ {
+ int c = GetChar();
+
+ if (c == '"')
+ break;
+
+ if (c == -1)
+ FATAL_INPUT_ERROR("unexpected EOF in string\n");
+
+ if (c == '\\')
+ {
+ c = GetChar();
+ }
+ }
+}
diff --git a/tools/scaninc/asm_file.h b/tools/scaninc/asm_file.h
new file mode 100644
index 00000000..ad99b757
--- /dev/null
+++ b/tools/scaninc/asm_file.h
@@ -0,0 +1,119 @@
+// Copyright(c) 2015-2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef ASM_FILE_H
+#define ASM_FILE_H
+
+#include <string>
+#include "scaninc.h"
+
+enum class IncDirectiveType
+{
+ None,
+ Include,
+ Incbin
+};
+
+class AsmFile
+{
+public:
+ AsmFile(std::string path);
+ ~AsmFile();
+ IncDirectiveType ReadUntilIncDirective(std::string& path);
+
+private:
+ char *m_buffer;
+ int m_pos;
+ int m_size;
+ int m_lineNum;
+ std::string m_path;
+
+ int GetChar()
+ {
+ if (m_pos >= m_size)
+ return -1;
+
+ int c = m_buffer[m_pos++];
+
+ if (c == '\r')
+ {
+ if (m_pos < m_size && m_buffer[m_pos++] == '\n')
+ {
+ m_lineNum++;
+ return '\n';
+ }
+ else
+ {
+ FATAL_INPUT_ERROR("CR line endings are not supported\n");
+ }
+ }
+
+ if (c == '\n')
+ m_lineNum++;
+
+ return c;
+ }
+
+ // No newline translation because it's not needed for any use of this function.
+ int PeekChar()
+ {
+ if (m_pos >= m_size)
+ return -1;
+
+ return m_buffer[m_pos];
+ }
+
+ void SkipTabsAndSpaces()
+ {
+ while (m_pos < m_size && (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' '))
+ m_pos++;
+ }
+
+ bool MatchIncDirective(std::string directiveName, std::string& path)
+ {
+ int length = directiveName.length();
+ int i;
+
+ for (i = 0; i < length && m_pos + i < m_size; i++)
+ if (directiveName[i] != m_buffer[m_pos + i])
+ return false;
+
+ if (i < length)
+ return false;
+
+ m_pos += length;
+
+ SkipTabsAndSpaces();
+
+ if (GetChar() != '"')
+ FATAL_INPUT_ERROR("no path after \".%s\" directive\n", directiveName.c_str());
+
+ path = ReadPath();
+
+ return true;
+ }
+
+ std::string ReadPath();
+ void SkipEndOfLineComment();
+ void SkipMultiLineComment();
+ void SkipString();
+};
+
+#endif // ASM_FILE_H
diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp
new file mode 100644
index 00000000..595f366c
--- /dev/null
+++ b/tools/scaninc/c_file.cpp
@@ -0,0 +1,307 @@
+// Copyright(c) 2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "c_file.h"
+
+CFile::CFile(std::string path)
+{
+ m_path = path;
+
+ FILE *fp = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ FATAL_ERROR("Failed to open \"%s\" for reading.\n", path.c_str());
+
+ std::fseek(fp, 0, SEEK_END);
+
+ m_size = std::ftell(fp);
+
+ m_buffer = new char[m_size + 1];
+ m_buffer[m_size] = 0;
+
+ std::rewind(fp);
+
+ if (std::fread(m_buffer, m_size, 1, fp) != 1)
+ FATAL_ERROR("Failed to read \"%s\".\n", path.c_str());
+
+ std::fclose(fp);
+
+ m_pos = 0;
+ m_lineNum = 1;
+}
+
+CFile::~CFile()
+{
+ delete[] m_buffer;
+}
+
+void CFile::FindIncbins()
+{
+ char stringChar = 0;
+
+ while (m_pos < m_size)
+ {
+ if (stringChar)
+ {
+ if (m_buffer[m_pos] == stringChar)
+ {
+ m_pos++;
+ stringChar = 0;
+ }
+ else if (m_buffer[m_pos] == '\\' && m_buffer[m_pos + 1] == stringChar)
+ {
+ m_pos += 2;
+ }
+ else
+ {
+ if (m_buffer[m_pos] == '\n')
+ m_lineNum++;
+ m_pos++;
+ }
+ }
+ else
+ {
+ SkipWhitespace();
+ CheckInclude();
+ CheckIncbin();
+
+ if (m_pos >= m_size)
+ break;
+
+ char c = m_buffer[m_pos++];
+
+ if (c == '\n')
+ m_lineNum++;
+ else if (c == '"')
+ stringChar = '"';
+ else if (c == '\'')
+ stringChar = '\'';
+ else if (c == 0)
+ FATAL_INPUT_ERROR("unexpected null character");
+ }
+ }
+}
+
+bool CFile::ConsumeHorizontalWhitespace()
+{
+ if (m_buffer[m_pos] == '\t' || m_buffer[m_pos] == ' ')
+ {
+ m_pos++;
+ return true;
+ }
+
+ return false;
+}
+
+bool CFile::ConsumeNewline()
+{
+ if (m_buffer[m_pos] == '\n')
+ {
+ m_pos++;
+ m_lineNum++;
+ return true;
+ }
+
+ if (m_buffer[m_pos] == '\r' && m_buffer[m_pos + 1] == '\n')
+ {
+ m_pos += 2;
+ m_lineNum++;
+ return true;
+ }
+
+ return false;
+}
+
+bool CFile::ConsumeComment()
+{
+ if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '*')
+ {
+ m_pos += 2;
+ while (m_buffer[m_pos] != '*' || m_buffer[m_pos + 1] != '/')
+ {
+ if (m_buffer[m_pos] == 0)
+ return false;
+ if (!ConsumeNewline())
+ m_pos++;
+ }
+ m_pos += 2;
+ return true;
+ }
+ else if (m_buffer[m_pos] == '/' && m_buffer[m_pos + 1] == '/')
+ {
+ m_pos += 2;
+ while (!ConsumeNewline())
+ {
+ if (m_buffer[m_pos] == 0)
+ return false;
+ m_pos++;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void CFile::SkipWhitespace()
+{
+ while (ConsumeHorizontalWhitespace() || ConsumeNewline() || ConsumeComment())
+ ;
+}
+
+bool CFile::CheckIdentifier(const std::string& ident)
+{
+ unsigned int i;
+
+ for (i = 0; i < ident.length() && m_pos + i < (unsigned)m_size; i++)
+ if (ident[i] != m_buffer[m_pos + i])
+ return false;
+
+ return (i == ident.length());
+}
+
+void CFile::CheckInclude()
+{
+ if (m_buffer[m_pos] != '#')
+ return;
+
+ std::string ident = "#include";
+
+ if (!CheckIdentifier(ident))
+ {
+ return;
+ }
+
+ m_pos += ident.length();
+
+ ConsumeHorizontalWhitespace();
+
+ std::string path = ReadPath();
+
+ if (!path.empty()) {
+ m_includes.emplace(path);
+ }
+}
+
+void CFile::CheckIncbin()
+{
+ // Optimization: assume most lines are not incbins
+ if (!(m_buffer[m_pos+0] == 'I'
+ && m_buffer[m_pos+1] == 'N'
+ && m_buffer[m_pos+2] == 'C'
+ && m_buffer[m_pos+3] == 'B'
+ && m_buffer[m_pos+4] == 'I'
+ && m_buffer[m_pos+5] == 'N'
+ && m_buffer[m_pos+6] == '_'))
+ {
+ return;
+ }
+
+ std::string idents[6] = { "INCBIN_S8", "INCBIN_U8", "INCBIN_S16", "INCBIN_U16", "INCBIN_S32", "INCBIN_U32" };
+ int incbinType = -1;
+
+ for (int i = 0; i < 6; i++)
+ {
+ if (CheckIdentifier(idents[i]))
+ {
+ incbinType = i;
+ break;
+ }
+ }
+
+ if (incbinType == -1)
+ return;
+
+ long oldPos = m_pos;
+ long oldLineNum = m_lineNum;
+
+ m_pos += idents[incbinType].length();
+
+ SkipWhitespace();
+
+ if (m_buffer[m_pos] != '(')
+ {
+ m_pos = oldPos;
+ m_lineNum = oldLineNum;
+ return;
+ }
+
+ m_pos++;
+
+ while (true)
+ {
+ SkipWhitespace();
+
+ std::string path = ReadPath();
+
+ SkipWhitespace();
+
+ m_incbins.emplace(path);
+
+ if (m_buffer[m_pos] != ',')
+ break;
+
+ m_pos++;
+ }
+
+ if (m_buffer[m_pos] != ')')
+ FATAL_INPUT_ERROR("expected ')'");
+
+ m_pos++;
+
+}
+
+std::string CFile::ReadPath()
+{
+ if (m_buffer[m_pos] != '"')
+ {
+ if (m_buffer[m_pos] == '<')
+ {
+ return std::string();
+ }
+ FATAL_INPUT_ERROR("expected '\"' or '<'");
+ }
+
+ m_pos++;
+
+ int startPos = m_pos;
+
+ while (m_buffer[m_pos] != '"')
+ {
+ if (m_buffer[m_pos] == 0)
+ {
+ if (m_pos >= m_size)
+ FATAL_INPUT_ERROR("unexpected EOF in path string");
+ else
+ FATAL_INPUT_ERROR("unexpected null character in path string");
+ }
+
+ if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n')
+ FATAL_INPUT_ERROR("unexpected end of line character in path string");
+
+ if (m_buffer[m_pos] == '\\')
+ FATAL_INPUT_ERROR("unexpected escape in path string");
+
+ m_pos++;
+ }
+
+ m_pos++;
+
+ return std::string(m_buffer + startPos, m_pos - 1 - startPos);
+}
diff --git a/tools/scaninc/c_file.h b/tools/scaninc/c_file.h
new file mode 100644
index 00000000..618901b8
--- /dev/null
+++ b/tools/scaninc/c_file.h
@@ -0,0 +1,57 @@
+// Copyright(c) 2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef C_FILE_H
+#define C_FILE_H
+
+#include <string>
+#include <set>
+#include <memory>
+#include "scaninc.h"
+
+class CFile
+{
+public:
+ CFile(std::string path);
+ ~CFile();
+ void FindIncbins();
+ const std::set<std::string>& GetIncbins() { return m_incbins; }
+ const std::set<std::string>& GetIncludes() { return m_includes; }
+
+private:
+ char *m_buffer;
+ int m_pos;
+ int m_size;
+ int m_lineNum;
+ std::string m_path;
+ std::set<std::string> m_incbins;
+ std::set<std::string> m_includes;
+
+ bool ConsumeHorizontalWhitespace();
+ bool ConsumeNewline();
+ bool ConsumeComment();
+ void SkipWhitespace();
+ bool CheckIdentifier(const std::string& ident);
+ void CheckInclude();
+ void CheckIncbin();
+ std::string ReadPath();
+};
+
+#endif // C_FILE_H
diff --git a/tools/scaninc/scaninc.cpp b/tools/scaninc/scaninc.cpp
new file mode 100644
index 00000000..b95cbd03
--- /dev/null
+++ b/tools/scaninc/scaninc.cpp
@@ -0,0 +1,121 @@
+// Copyright(c) 2015-2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include <cstdio>
+#include <cstdlib>
+#include <list>
+#include <queue>
+#include <set>
+#include <string>
+#include "scaninc.h"
+#include "source_file.h"
+
+bool CanOpenFile(std::string path)
+{
+ FILE *fp = std::fopen(path.c_str(), "rb");
+
+ if (fp == NULL)
+ return false;
+
+ std::fclose(fp);
+ return true;
+}
+
+const char *const USAGE = "Usage: scaninc [-I INCLUDE_PATH] FILE_PATH\n";
+
+int main(int argc, char **argv)
+{
+ std::queue<std::string> filesToProcess;
+ std::set<std::string> dependencies;
+
+ std::vector<std::string> includeDirs;
+
+ argc--;
+ argv++;
+
+ while (argc > 1)
+ {
+ std::string arg(argv[0]);
+ if (arg.substr(0, 2) == "-I")
+ {
+ std::string includeDir = arg.substr(2);
+ if (includeDir.empty())
+ {
+ argc--;
+ argv++;
+ includeDir = std::string(argv[0]);
+ }
+ if (!includeDir.empty() && includeDir.back() != '/')
+ {
+ includeDir += '/';
+ }
+ includeDirs.push_back(includeDir);
+ }
+ else
+ {
+ FATAL_ERROR(USAGE);
+ }
+ argc--;
+ argv++;
+ }
+
+ if (argc != 1) {
+ FATAL_ERROR(USAGE);
+ }
+
+ std::string initialPath(argv[0]);
+
+ filesToProcess.push(initialPath);
+
+ while (!filesToProcess.empty())
+ {
+ std::string filePath = filesToProcess.front();
+ SourceFile file(filePath);
+ filesToProcess.pop();
+
+ includeDirs.push_back(file.GetSrcDir());
+ for (auto incbin : file.GetIncbins())
+ {
+ dependencies.insert(incbin);
+ }
+ for (auto include : file.GetIncludes())
+ {
+ for (auto includeDir : includeDirs)
+ {
+ std::string path(includeDir + include);
+ if (CanOpenFile(path))
+ {
+ bool inserted = dependencies.insert(path).second;
+ if (inserted)
+ {
+ filesToProcess.push(path);
+ }
+ break;
+ }
+ }
+ }
+ includeDirs.pop_back();
+ }
+
+ for (const std::string &path : dependencies)
+ {
+ std::printf("%s\n", path.c_str());
+ }
+}
diff --git a/tools/scaninc/scaninc.h b/tools/scaninc/scaninc.h
new file mode 100644
index 00000000..30cc9611
--- /dev/null
+++ b/tools/scaninc/scaninc.h
@@ -0,0 +1,59 @@
+// Copyright(c) 2015-2017 YamaArashi
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef SCANINC_H
+#define SCANINC_H
+
+#include <cstdio>
+#include <cstdlib>
+
+#ifdef _MSC_VER
+
+#define FATAL_INPUT_ERROR(format, ...) \
+do { \
+ fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, __VA_ARGS__); \
+ exit(1); \
+} while (0)
+
+#define FATAL_ERROR(format, ...) \
+do { \
+ fprintf(stderr, format, __VA_ARGS__); \
+ exit(1); \
+} while (0)
+
+#else
+
+#define FATAL_INPUT_ERROR(format, ...) \
+do { \
+ fprintf(stderr, "%s:%d " format, m_path.c_str(), m_lineNum, ##__VA_ARGS__); \
+ exit(1); \
+} while (0)
+
+#define FATAL_ERROR(format, ...) \
+do { \
+ fprintf(stderr, format, ##__VA_ARGS__); \
+ exit(1); \
+} while (0)
+
+#endif // _MSC_VER
+
+#define SCANINC_MAX_PATH 255
+
+#endif // SCANINC_H
diff --git a/tools/scaninc/source_file.cpp b/tools/scaninc/source_file.cpp
new file mode 100644
index 00000000..f23ff6db
--- /dev/null
+++ b/tools/scaninc/source_file.cpp
@@ -0,0 +1,125 @@
+// Copyright(c) 2019 Phlosioneer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include <new>
+#include "source_file.h"
+
+
+SourceFileType GetFileType(std::string& path)
+{
+ std::size_t pos = path.find_last_of('.');
+
+ if (pos == std::string::npos)
+ FATAL_ERROR("no file extension in path \"%s\"\n", path.c_str());
+
+ std::string extension = path.substr(pos + 1);
+
+ if (extension == "c")
+ return SourceFileType::Cpp;
+ else if (extension == "s")
+ return SourceFileType::Asm;
+ else if (extension == "h")
+ return SourceFileType::Header;
+ else if (extension == "inc")
+ return SourceFileType::Inc;
+ else
+ FATAL_ERROR("Unrecognized extension \"%s\"\n", extension.c_str());
+
+ // Unreachable
+ return SourceFileType::Cpp;
+}
+
+std::string GetDir(std::string& path)
+{
+ std::size_t slash = path.rfind('/');
+
+ if (slash != std::string::npos)
+ return path.substr(0, slash + 1);
+ else
+ return std::string("");
+}
+
+SourceFile::SourceFile(std::string path)
+{
+ m_file_type = GetFileType(path);
+
+ m_src_dir = GetDir(path);
+
+ if (m_file_type == SourceFileType::Cpp
+ || m_file_type == SourceFileType::Header)
+ {
+ new (&m_source_file.c_file) CFile(path);
+ m_source_file.c_file.FindIncbins();
+ }
+ else
+ {
+ AsmFile file(path);
+ std::set<std::string> incbins;
+ std::set<std::string> includes;
+
+ IncDirectiveType incDirectiveType;
+ std::string outputPath;
+
+ while ((incDirectiveType = file.ReadUntilIncDirective(outputPath)) != IncDirectiveType::None)
+ {
+ if (incDirectiveType == IncDirectiveType::Include)
+ includes.insert(outputPath);
+ else
+ incbins.insert(outputPath);
+ }
+
+ new (&m_source_file.asm_wrapper) SourceFile::InnerUnion::AsmWrapper{incbins, includes};
+ }
+}
+
+SourceFile::~SourceFile()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ {
+ m_source_file.c_file.~CFile();
+ }
+ else
+ {
+ m_source_file.asm_wrapper.asm_incbins.~set();
+ m_source_file.asm_wrapper.asm_includes.~set();
+ }
+}
+
+const std::set<std::string>& SourceFile::GetIncbins()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ return m_source_file.c_file.GetIncbins();
+ else
+ return m_source_file.asm_wrapper.asm_incbins;
+}
+
+const std::set<std::string>& SourceFile::GetIncludes()
+{
+ if (m_file_type == SourceFileType::Cpp || m_file_type == SourceFileType::Header)
+ return m_source_file.c_file.GetIncludes();
+ else
+ return m_source_file.asm_wrapper.asm_includes;
+}
+
+std::string& SourceFile::GetSrcDir()
+{
+ return m_src_dir;
+}
+
diff --git a/tools/scaninc/source_file.h b/tools/scaninc/source_file.h
new file mode 100644
index 00000000..f7b6412b
--- /dev/null
+++ b/tools/scaninc/source_file.h
@@ -0,0 +1,71 @@
+// Copyright(c) 2019 Phlosioneer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#ifndef SOURCE_FILE_H
+#define SOURCE_FILE_H
+
+#include <string>
+#include "scaninc.h"
+#include "asm_file.h"
+#include "c_file.h"
+
+enum class SourceFileType
+{
+ Cpp,
+ Header,
+ Asm,
+ Inc
+};
+
+SourceFileType GetFileType(std::string& path);
+
+class SourceFile
+{
+public:
+
+ SourceFile(std::string path);
+ ~SourceFile();
+ SourceFile(SourceFile const&) = delete;
+ SourceFile(SourceFile&&) = delete;
+ SourceFile& operator =(SourceFile const&) = delete;
+ SourceFile& operator =(SourceFile&&) = delete;
+ bool HasIncbins();
+ const std::set<std::string>& GetIncbins();
+ const std::set<std::string>& GetIncludes();
+ std::string& GetSrcDir();
+
+private:
+ union InnerUnion {
+ CFile c_file;
+ struct AsmWrapper {
+ std::set<std::string> asm_incbins;
+ std::set<std::string> asm_includes;
+ } asm_wrapper;
+
+ // Construction and destruction handled by SourceFile.
+ InnerUnion() {};
+ ~InnerUnion() {};
+ } m_source_file;
+ SourceFileType m_file_type;
+ std::string m_src_dir;
+};
+
+#endif // SOURCE_FILE_H
+
diff --git a/undefined_syms.txt b/undefined_syms.txt
index 9fca8cb5..c1f28b96 100644
--- a/undefined_syms.txt
+++ b/undefined_syms.txt
@@ -55,7 +55,7 @@ OSi_vramLockId = 0x021D37E8;
cardi_common = 0x021D55C0;
// Overlay
-FUN_021D74E0 = 0x021D74E0;
+MOD05_021D74E0 = 0x021D74E0;
FUN_021D76AC = 0x021D76AC;
gUnk021D76C8 = 0x021D76C8;
FUN_021D77C4 = 0x021D77C4;