1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - FS - demos - arc-1
3 File: main.c
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-10-02 #$
14 $Rev: 8827 $
15 $Author: yosizaki $
16 *---------------------------------------------------------------------------*/
17
18
19 #include <nitro.h>
20
21
22 // Duplicate ROM archive structure
23 typedef struct MyRomArchive
24 {
25 FSArchive arc[1];
26 u32 default_dma_no;
27 u32 card_lock_id;
28
29 }
30 MyRomArchive;
31
32 // Process that is run upon completion of an asynchronous read operation from a ROM
MyRom_OnReadDone(void * arc)33 static void MyRom_OnReadDone(void *arc)
34 {
35 // Notify the archive of completion.
36 FS_NotifyArchiveAsyncEnd((FSArchive *)arc, FS_RESULT_SUCCESS);
37 }
38
39 // Read access callback from the FS library to the archive
MyRom_ReadCallback(FSArchive * arc,void * dst,u32 src,u32 len)40 static FSResult MyRom_ReadCallback(FSArchive *arc, void *dst, u32 src, u32 len)
41 {
42 MyRomArchive *const p_rom = (MyRomArchive *)arc;
43 CARD_ReadRomAsync(p_rom->default_dma_no,
44 (const void *)(FS_GetArchiveBase(arc) + src), dst, len,
45 MyRom_OnReadDone, arc);
46 return FS_RESULT_PROC_ASYNC;
47 }
48
49 // Write callback from the FS library to the archive
50 // This returns FS_RESULT_UNSUPPORTED in a user procedure and will not be called.
MyRom_WriteDummyCallback(FSArchive * arc,const void * src,u32 dst,u32 len)51 static FSResult MyRom_WriteDummyCallback(FSArchive *arc, const void *src, u32 dst, u32 len)
52 {
53 (void)arc;
54 (void)src;
55 (void)dst;
56 (void)len;
57 return FS_RESULT_FAILURE;
58 }
59
60 // User procedure
61 // This locks the ROM before the first command is started and continues to do so until after the last command is complete.
62 // Its response to write operations is "unsupported".
63 // Everything else has the default behavior.
MyRom_ArchiveProc(FSFile * file,FSCommandType cmd)64 static FSResult MyRom_ArchiveProc(FSFile *file, FSCommandType cmd)
65 {
66 MyRomArchive *const p_rom = (MyRomArchive *) FS_GetAttachedArchive(file);
67 switch (cmd)
68 {
69 case FS_COMMAND_ACTIVATE:
70 CARD_LockRom((u16)p_rom->card_lock_id);
71 return FS_RESULT_SUCCESS;
72 case FS_COMMAND_IDLE:
73 CARD_UnlockRom((u16)p_rom->card_lock_id);
74 return FS_RESULT_SUCCESS;
75 case FS_COMMAND_WRITEFILE:
76 return FS_RESULT_UNSUPPORTED;
77 default:
78 return FS_RESULT_PROC_UNKNOWN;
79 }
80 }
81
82 // Make DMA assignments and register and load archives
MyRom_Create(MyRomArchive * p_rom,const char * name,u32 base,const CARDRomRegion * fnt,const CARDRomRegion * fat)83 static void MyRom_Create(MyRomArchive *p_rom, const char *name,
84 u32 base, const CARDRomRegion *fnt, const CARDRomRegion *fat)
85 {
86 FS_InitArchive(p_rom->arc);
87 p_rom->default_dma_no = FS_DMA_NOT_USE;
88 p_rom->card_lock_id = (u32)OS_GetLockID();
89 if (!FS_RegisterArchiveName(p_rom->arc, name, (u32)STD_GetStringLength(name)))
90 {
91 OS_TPanic("error! FS_RegisterArchiveName(%s) failed.\n", name);
92 }
93 else
94 {
95 FS_SetArchiveProc(p_rom->arc, MyRom_ArchiveProc,
96 FS_ARCHIVE_PROC_WRITEFILE | FS_ARCHIVE_PROC_ACTIVATE | FS_ARCHIVE_PROC_IDLE);
97 if (!FS_LoadArchive(p_rom->arc, base,
98 fat->offset, fat->length, fnt->offset, fnt->length,
99 MyRom_ReadCallback, MyRom_WriteDummyCallback))
100 {
101 OS_TPanic("error! FS_LoadArchive() failed.\n");
102 }
103 }
104 }
105
106 // List the directories in a ROM archive
DumpRomDirectorySub(int tab,FSDirEntry * pe)107 static void DumpRomDirectorySub(int tab, FSDirEntry *pe)
108 {
109 FSFile d;
110 FS_InitFile(&d);
111 OS_TPrintf("%*s%s/\n", tab, "", pe->name);
112 if (FS_SeekDir(&d, &pe->dir_id))
113 {
114 tab += 4;
115 while (FS_ReadDir(&d, pe))
116 {
117 if (pe->is_directory)
118 {
119 DumpRomDirectorySub(tab, pe);
120 }
121 else
122 {
123 OS_Printf("%*s%s\n", tab, "", pe->name);
124 }
125 }
126 }
127 }
DumpRomDir(const char * path)128 static void DumpRomDir(const char *path)
129 {
130 FSDirEntry entry;
131 FSFile dir;
132 FS_InitFile(&dir);
133 (void)FS_ChangeDir(path);
134 (void)FS_FindDir(&dir, "");
135 entry.name[0] = '\0';
136 (void)FS_TellDir(&dir, &entry.dir_id);
137 DumpRomDirectorySub(0, &entry);
138 }
139
NitroMain(void)140 void NitroMain(void)
141 {
142 static MyRomArchive myrom_dup;
143 static MyRomArchive myrom_sub;
144
145 // Initialize the OS and memory allocator
146 OS_Init();
147 {
148 OSHeapHandle hh;
149 void *tmp;
150 tmp = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
151 OS_SetArenaLo(OS_ARENA_MAIN, tmp);
152 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
153 if (hh < 0)
154 {
155 OS_TPanic("ARM9: Fail to create heap...\n");
156 }
157 (void)OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
158 }
159 (void)OS_EnableIrq();
160 // Initialize the FS
161 FS_Init(3);
162 {
163 u32 need_size = FS_GetTableSize();
164 void *p_table = OS_Alloc(need_size);
165 SDK_ASSERT(p_table != NULL);
166 (void)FS_LoadTable(p_table, need_size);
167 }
168
169 OS_TPrintf("\n"
170 "++++++++++++++++++++++++++++++++++++++++\n"
171 "test 1 : query default \"rom\" directories ... \n\n");
172
173 DumpRomDir("rom:/");
174
175 OS_TPrintf("\n"
176 "++++++++++++++++++++++++++++++++++++++++\n"
177 "test 2 : query duplication archive \"dup\" directories ... \n\n");
178 {
179 const u32 base = 0;
180 const CARDRomRegion *fnt = CARD_GetRomRegionFNT();
181 const CARDRomRegion *fat = CARD_GetRomRegionFAT();
182
183 MyRom_Create(&myrom_dup, "dup", base, fnt, fat);
184 DumpRomDir("dup:/");
185 }
186
187 OS_TPrintf("\n"
188 "++++++++++++++++++++++++++++++++++++++++\n"
189 "test 3 : query sub-program archive \"sub\" directories ... \n\n");
190 {
191 FSFile sub_binary;
192 FS_InitFile(&sub_binary);
193 if (!FS_OpenFileEx(&sub_binary, "rom:/main.srl", FS_FILEMODE_R))
194 {
195 OS_Panic("failed to open sub-program binary");
196 }
197 else
198 {
199 const u32 base = FS_GetFileImageTop(&sub_binary);
200 CARDRomHeader header;
201 (void)FS_ReadFile(&sub_binary, &header, sizeof(header));
202 (void)FS_CloseFile(&sub_binary);
203
204 MyRom_Create(&myrom_sub, "sub", base, &header.fnt, &header.fat);
205 DumpRomDir("sub:/");
206 }
207 }
208
209 OS_TPrintf("\n" "++++++++++++++++++++++++++++++++++++++++\n" "end\n\n");
210 OS_Terminate();
211 }
212