summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/arm9.lcf1
-rw-r--r--arm9/asm/FS_archive.asm.s (renamed from arm9/asm/FS_archive.s)289
-rw-r--r--arm9/asm/FS_rom.s1
-rw-r--r--arm9/lib/include/FS_archive.h56
-rw-r--r--arm9/lib/include/FS_command.h9
-rw-r--r--arm9/lib/include/FS_file.h20
-rw-r--r--arm9/lib/include/OS_thread.h1
-rw-r--r--arm9/lib/src/FS_archive.c147
-rw-r--r--arm9/lib/src/FS_file.c10
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)