diff options
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/CARD_rom.h | 11 | ||||
-rw-r--r-- | arm9/lib/include/FS_archive.h | 113 | ||||
-rw-r--r-- | arm9/lib/include/FS_file.h | 179 | ||||
-rw-r--r-- | arm9/lib/include/FS_overlay.h | 41 | ||||
-rw-r--r-- | arm9/lib/include/FS_rom.h | 6 | ||||
-rw-r--r-- | arm9/lib/include/MI_byteAccess.h | 9 | ||||
-rw-r--r-- | arm9/lib/include/MI_exMemory.h | 9 | ||||
-rw-r--r-- | arm9/lib/include/OS_system.h | 1 | ||||
-rw-r--r-- | arm9/lib/include/OS_thread.h | 14 | ||||
-rw-r--r-- | arm9/lib/include/mmap.h | 2 | ||||
-rw-r--r-- | arm9/lib/include/mmap_global.h | 4 | ||||
-rw-r--r-- | arm9/lib/src/FS_file.c | 258 |
12 files changed, 647 insertions, 0 deletions
diff --git a/arm9/lib/include/CARD_rom.h b/arm9/lib/include/CARD_rom.h new file mode 100644 index 00000000..327bc995 --- /dev/null +++ b/arm9/lib/include/CARD_rom.h @@ -0,0 +1,11 @@ +#ifndef NITRO_CARD_ROM_H_ +#define NITRO_CARD_ROM_H_ + +typedef struct +{ + u32 offset; + u32 length; +} +CARDRomRegion; + +#endif //NITRO_CARD_ROM_H_ diff --git a/arm9/lib/include/FS_archive.h b/arm9/lib/include/FS_archive.h new file mode 100644 index 00000000..66840b32 --- /dev/null +++ b/arm9/lib/include/FS_archive.h @@ -0,0 +1,113 @@ +#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; + +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 FSArchive +{ + union + { + char ptr[4]; + u32 pack; + } name; + struct FSArchive * prev; + struct FSArchive * next; + 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; +} + +BOOL FSi_SendCommand(struct FSFile * file, FSCommandType command); +BOOL FSi_ExecuteSyncCommand(struct FSFile * file); + +#endif //NITRO_FS_ARCHIVE_H_ diff --git a/arm9/lib/include/FS_file.h b/arm9/lib/include/FS_file.h new file mode 100644 index 00000000..4871b660 --- /dev/null +++ b/arm9/lib/include/FS_file.h @@ -0,0 +1,179 @@ +#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 + +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); + +#endif //NITRO_FS_FILE_H_ diff --git a/arm9/lib/include/FS_overlay.h b/arm9/lib/include/FS_overlay.h new file mode 100644 index 00000000..c2634509 --- /dev/null +++ b/arm9/lib/include/FS_overlay.h @@ -0,0 +1,41 @@ +#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; + +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); +void FS_CloseFile(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..fc62b579 --- /dev/null +++ b/arm9/lib/include/FS_rom.h @@ -0,0 +1,6 @@ +#ifndef NITRO_FS_ROM_H_ +#define NITRO_FS_ROM_H_ + +void FSi_InitRom(u32 default_dma_no); + +#endif //NITRO_FS_ROM_H_ diff --git a/arm9/lib/include/MI_byteAccess.h b/arm9/lib/include/MI_byteAccess.h new file mode 100644 index 00000000..10dae4c9 --- /dev/null +++ b/arm9/lib/include/MI_byteAccess.h @@ -0,0 +1,9 @@ +#ifndef NITRO_MI_BYTEACCESS_H_ +#define NITRO_MI_BYTEACCESS_H_ + +static inline u8 MI_ReadByte(const void *address) +{ + return *(u8 *)address; +} + +#endif //NITRO_MI_BYTEACCESS_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/OS_system.h b/arm9/lib/include/OS_system.h index 9a79c0d1..65c58f57 100644 --- a/arm9/lib/include/OS_system.h +++ b/arm9/lib/include/OS_system.h @@ -5,6 +5,7 @@ #ifndef POKEDIAMOND_OS_SYSTEM_H #define POKEDIAMOND_OS_SYSTEM_H +#include "function_target.h" #include "consts.h" #include "function_target.h" diff --git a/arm9/lib/include/OS_thread.h b/arm9/lib/include/OS_thread.h index 4fb70bf7..8820a7a0 100644 --- a/arm9/lib/include/OS_thread.h +++ b/arm9/lib/include/OS_thread.h @@ -7,6 +7,14 @@ typedef struct _OSThread OSThread; +struct _OSThreadQueue +{ + OSThread *head; + OSThread *tail; +}; + +typedef struct _OSThreadQueue OSThreadQueue; + typedef struct OSThreadInfo { u16 isNeedRescheduling; u16 irqDepth; @@ -20,4 +28,10 @@ struct _OSThread u8 padding[0x80]; //todo: not the correct size but idfk }; +void OS_SleepThread(OSThreadQueue * queue); +static inline void OS_InitThreadQueue(OSThreadQueue * queue) +{ + queue->head = queue->tail = NULL; +} + #endif //POKEDIAMOND_OS_THREAD_H 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/include/mmap_global.h b/arm9/lib/include/mmap_global.h new file mode 100644 index 00000000..e657e46f --- /dev/null +++ b/arm9/lib/include/mmap_global.h @@ -0,0 +1,4 @@ +#ifndef NITRO_MMAP_GLOBAL_H_ +#define NITRO_MMAP_GLOBAL_H_ + +#endif //NITRO_MMAP_GLOBAL_H_ diff --git a/arm9/lib/src/FS_file.c b/arm9/lib/src/FS_file.c new file mode 100644 index 00000000..8ca89af8 --- /dev/null +++ b/arm9/lib/src/FS_file.c @@ -0,0 +1,258 @@ +#include "nitro.h" +#include "MI_byteAccess.h" +#include "FS_rom.h" +#include "FS_file.h" + +extern FSDirPos current_dir_pos; +BOOL is_init = FALSE; + +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) + { + is_init = TRUE; + FSi_InitRom(default_dma_no); + } +} + +BOOL FS_IsAvailable(void) +{ + return is_init; +} + +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); +} + +int FSi_ReadFileCore(FSFile * p_file, void * dst, s32 len, BOOL async) +{ + { + const s32 pos = (s32)p_file->prop.file.pos; + const s32 rest = (s32)p_file->prop.file.bottom - pos; + const u32 org = (u32)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 = (u32)(len); + if (!async) + p_file->stat |= FS_FILE_STATUS_SYNC; + (void)FSi_SendCommand(p_file, FS_COMMAND_READFILE); + if (!async) + { + if (FS_WaitAsync(p_file)) + len = (s32)p_file->prop.file.pos - pos; + else + len = -1; + } + } + return len; +} + +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; +} + +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; +} + +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; +} + +BOOL FS_OpenFile(FSFile * p_file, const char * path) +{ + FSFileID file_id; + return FS_ConvertPathToFileID(&file_id, path) && FS_OpenFileFast(p_file, file_id); +} + +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; +} + +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); +} + +int FS_ReadFileAsync(FSFile * p_file, void * dst, s32 len) +{ + return FSi_ReadFileCore(p_file, dst, len, TRUE); +} + +int FS_ReadFile(FSFile * p_file, void * dst, s32 len) +{ + return FSi_ReadFileCore(p_file, dst, len, FALSE); +} + +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; +} + +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; +} |