diff options
-rw-r--r-- | arm9/arm9.lcf | 1 | ||||
-rw-r--r-- | arm9/asm/FS_archive.asm.s (renamed from arm9/asm/FS_archive.s) | 289 | ||||
-rw-r--r-- | arm9/asm/FS_rom.s | 1 | ||||
-rw-r--r-- | arm9/lib/include/FS_archive.h | 56 | ||||
-rw-r--r-- | arm9/lib/include/FS_command.h | 9 | ||||
-rw-r--r-- | arm9/lib/include/FS_file.h | 20 | ||||
-rw-r--r-- | arm9/lib/include/OS_thread.h | 1 | ||||
-rw-r--r-- | arm9/lib/src/FS_archive.c | 147 | ||||
-rw-r--r-- | arm9/lib/src/FS_file.c | 10 |
9 files changed, 242 insertions, 292 deletions
diff --git a/arm9/arm9.lcf b/arm9/arm9.lcf index 7a4a43fb..b98c9b69 100644 --- a/arm9/arm9.lcf +++ b/arm9/arm9.lcf @@ -192,6 +192,7 @@ SECTIONS { PXI_fifo.o (.text) FS_command.o (.text) FS_command_default.o (.text) + FS_archive.asm.o (.text) FS_archive.o (.text) FS_file.o (.text) FS_rom.o (.text) diff --git a/arm9/asm/FS_archive.s b/arm9/asm/FS_archive.asm.s index 51a3e121..fd205e5a 100644 --- a/arm9/asm/FS_archive.s +++ b/arm9/asm/FS_archive.asm.s @@ -2,6 +2,14 @@ .include "global.inc" .section .text + .extern FSi_GetPackedName + .extern FSi_ReadMemCallback + .extern FSi_WriteMemCallback + .extern FSi_ReadMemoryCore + .extern FSi_NextCommand + .extern FSi_ExecuteAsyncCommand + .extern FSi_ExecuteSyncCommand + arm_func_start FS_NotifyArchiveAsyncEnd FS_NotifyArchiveAsyncEnd: ; 0x020D0B40 stmdb sp!, {r4-r6,lr} @@ -614,284 +622,3 @@ _020D1378: 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 diff --git a/arm9/asm/FS_rom.s b/arm9/asm/FS_rom.s index 61a7c521..dc7baf6c 100644 --- a/arm9/asm/FS_rom.s +++ b/arm9/asm/FS_rom.s @@ -236,7 +236,6 @@ FSi_OnRomReadDone: ; 0x020D2018 stmdb sp!, {r4,lr} mov r4, r0 bl CARD_IsPulledOut -_020D2024: cmp r0, #0x0 movne r1, #0x5 moveq r1, #0x0 diff --git a/arm9/lib/include/FS_archive.h b/arm9/lib/include/FS_archive.h index 66840b32..b39e7738 100644 --- a/arm9/lib/include/FS_archive.h +++ b/arm9/lib/include/FS_archive.h @@ -47,6 +47,37 @@ typedef enum { 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) + typedef enum { FS_RESULT_SUCCESS = 0, FS_RESULT_FAILURE, @@ -107,6 +138,31 @@ 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; +} + BOOL FSi_SendCommand(struct FSFile * file, FSCommandType command); BOOL FSi_ExecuteSyncCommand(struct FSFile * file); diff --git a/arm9/lib/include/FS_command.h b/arm9/lib/include/FS_command.h new file mode 100644 index 00000000..db878f3f --- /dev/null +++ b/arm9/lib/include/FS_command.h @@ -0,0 +1,9 @@ +#ifndef NITRO_FS_COMMAND_H_ +#define NITRO_FS_COMMAND_H_ + +#include "FS_file.h" + +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 index 89f69d86..92e2149e 100644 --- a/arm9/lib/include/FS_file.h +++ b/arm9/lib/include/FS_file.h @@ -189,4 +189,24 @@ 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; +} + #endif //NITRO_FS_FILE_H_ diff --git a/arm9/lib/include/OS_thread.h b/arm9/lib/include/OS_thread.h index 8820a7a0..c5602559 100644 --- a/arm9/lib/include/OS_thread.h +++ b/arm9/lib/include/OS_thread.h @@ -29,6 +29,7 @@ struct _OSThread }; 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/src/FS_archive.c b/arm9/lib/src/FS_archive.c new file mode 100644 index 00000000..39daa324 --- /dev/null +++ b/arm9/lib/src/FS_archive.c @@ -0,0 +1,147 @@ +#include "FS_archive.h" +#include "FS_file.h" +#include "FS_command.h" +#include "MI_memory.h" +#include "MI_byteAccess.h" + +FSArchive * arc_list = NULL; +FSDirPos current_dir_pos; + +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; +} + +FSResult FSi_ReadMemCallback(FSArchive * p_arc, u8 * dest, u32 offset, u32 size) +{ + MI_CpuCopy8((const void *)FS_GetArchiveOffset(p_arc, offset), dest, size); + return FS_RESULT_SUCCESS; +} + +FSResult FSi_WriteMemCallback(FSArchive * p_arc, const u8 * src, u32 offset, u32 size) +{ + MI_CpuCopy8(src, (void *)FS_GetArchiveOffset(p_arc, offset), size); + return FS_RESULT_SUCCESS; +} + +FSResult FSi_ReadMemoryCore(FSArchive * p_arc, u8 * dest, u32 offset, u32 size) +{ + MI_CpuCopy8((const void *)offset, dest, size); + return FS_RESULT_SUCCESS; +} + +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; +} + +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); + } +} + +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); +} diff --git a/arm9/lib/src/FS_file.c b/arm9/lib/src/FS_file.c index 8ca89af8..479a5085 100644 --- a/arm9/lib/src/FS_file.c +++ b/arm9/lib/src/FS_file.c @@ -11,16 +11,6 @@ static inline BOOL FSi_IsSlash(u32 c) return (c == '/') || (c == '\\'); } -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; -} - void FS_Init(u32 default_dma_no) { if (!is_init) |