summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-05-07 19:55:15 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2020-05-07 19:55:15 -0400
commitab5676fcf0a728374d5495c1980f1e2459d0ba4e (patch)
treebf1eab8ad536cd34027d7c25145b362c35339516 /arm9/lib
parent994cfcbc9a1e42043b25ae3ab6471b8ecbd55ff1 (diff)
FS_command.c
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/FS_archive.h5
-rw-r--r--arm9/lib/include/FS_command.h2
-rw-r--r--arm9/lib/include/FSi_util.h7
-rw-r--r--arm9/lib/src/FS_command.c75
4 files changed, 89 insertions, 0 deletions
diff --git a/arm9/lib/include/FS_archive.h b/arm9/lib/include/FS_archive.h
index d7c2a785..3bbbbff7 100644
--- a/arm9/lib/include/FS_archive.h
+++ b/arm9/lib/include/FS_archive.h
@@ -175,6 +175,11 @@ 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;
diff --git a/arm9/lib/include/FS_command.h b/arm9/lib/include/FS_command.h
index db878f3f..b5e73bcf 100644
--- a/arm9/lib/include/FS_command.h
+++ b/arm9/lib/include/FS_command.h
@@ -3,6 +3,8 @@
#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);
diff --git a/arm9/lib/include/FSi_util.h b/arm9/lib/include/FSi_util.h
index 1012df13..1f6faf6f 100644
--- a/arm9/lib/include/FSi_util.h
+++ b/arm9/lib/include/FSi_util.h
@@ -20,6 +20,13 @@ static inline void FSi_CutFromListCore(FSFileLink *trg)
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;
diff --git a/arm9/lib/src/FS_command.c b/arm9/lib/src/FS_command.c
new file mode 100644
index 00000000..bc7839d8
--- /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"
+
+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);
+}
+
+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;
+}