1 /*---------------------------------------------------------------------------*
2 Project: Sample demo program for NAND library
3 File: safe.c
4 Programmer: HIRATSU Daisuke
5
6 Copyright (C) 2006 Nintendo. All rights reserved.
7
8 These coded instructions, statements, and computer programs contain
9 proprietary information of Nintendo of America Inc. and/or Nintendo
10 Company Ltd., and are protected by Federal copyright law. They may
11 not be disclosed to third parties or copied or duplicated in any form,
12 in whole or in part, without the prior written consent of Nintendo.
13
14 $Log: safe.c,v $
15 Revision 1.4 2007/05/07 12:50:37 hiratsu
16 Modified copy buffer size.
17
18 Revision 1.3 2007/04/23 09:32:13 hiratsu
19 Replaced NANDSafe series API with NANDSimpleSafe series API.
20
21 Revision 1.2 2006/08/12 12:00:54 hiratsu
22 Refactoring.
23
24 Revision 1.1 2006/07/24 07:24:03 hiratsu
25 This demo tells differences between normal Open/Close and SafeOpen/SafeClose.
26
27 *---------------------------------------------------------------------------*/
28
29 #include <revolution.h>
30 #include <revolution/nand.h>
31
32 #include <string.h>
33
34 #include "util.h"
35
36
37 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE) // Owner can read/write
38 #define ATTR 0x00 // No attributes.
39 #define COPYBUF_SIZE NAND_FSBLOCK_SIZE
40 #define FILE_SIZE (1*1024*1024)
41 #define SAFE_FILENAME "safe.dat"
42 #define UNSAFE_FILENAME "unsafe.dat"
43
44
45 static void checkFileData(const char *filename);
46 static void initFile(const char *filename);
47
48
checkFileData(const char * filename)49 static void checkFileData(const char *filename)
50 {
51 static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
52 int i = 0;
53 NANDFileInfo info;
54 s32 rc = NANDOpen(filename, &info, NAND_ACCESS_READ);
55 if(rc!=NAND_RESULT_OK)
56 {
57 printErrMsg(rc);
58 }
59
60 rc = NANDRead(&info, s_buf, FILE_SIZE);
61 if(rc!=FILE_SIZE)
62 {
63 printErrMsg(rc);
64 }
65
66 rc = NANDClose(&info);
67 if(rc!=NAND_RESULT_OK)
68 {
69 printErrMsg(rc);
70 }
71
72 OSReport("Checking anterior half and last half of %s ... ", filename);
73 if(memcmp(s_buf, s_buf+FILE_SIZE/2, FILE_SIZE/2)==0)
74 {
75 OSReport("Equivalent.\n");
76 }
77 else
78 {
79 OSReport("Different!\n");
80 }
81 }
82
83
initFile(const char * filename)84 static void initFile(const char *filename)
85 {
86 s32 rc = NANDCreate(filename, PERM, ATTR);
87 if(rc==NAND_RESULT_OK)
88 {
89 OSReport("Created %s.\n", filename);
90 }
91
92 if(rc==NAND_RESULT_OK || rc==NAND_RESULT_EXISTS)
93 {
94 static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
95 NANDFileInfo info;
96 rc = NANDOpen(filename, &info, NAND_ACCESS_WRITE);
97 if(rc!=NAND_RESULT_OK)
98 {
99 printErrMsg(rc);
100 }
101
102 memset(s_buf, 'A', FILE_SIZE);
103 rc = NANDWrite(&info, s_buf, FILE_SIZE);
104 if(rc!=FILE_SIZE)
105 {
106 printErrMsg(rc);
107 }
108
109 rc = NANDClose(&info);
110 if(rc!=NAND_RESULT_OK)
111 {
112 printErrMsg(rc);
113 }
114
115 OSReport("Now %s is filled with 'A'.\n", filename);
116 }
117 else
118 {
119 printErrMsg(rc);
120 OSHalt("Unexpected error.");
121 }
122 }
123
124
main(void)125 int main(void)
126 {
127 PADStatus pad[PAD_MAX_CONTROLLERS];
128 NANDFileInfo safeInfo, unsafeInfo;
129 static u8 aryB[FILE_SIZE/2] ATTRIBUTE_ALIGN(32);
130 static u8 copyBuf[COPYBUF_SIZE] ATTRIBUTE_ALIGN(32);
131 s32 rc = NAND_RESULT_FATAL_ERROR;
132 u8 type = 0x00;
133
134 NANDInit();
135 PADInit();
136 VIInit();
137
138 memset(aryB, 'B', FILE_SIZE/2);
139
140 rc = NANDGetType(SAFE_FILENAME, &type);
141 if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
142 {
143 checkFileData(SAFE_FILENAME);
144 }
145
146 rc = NANDGetType(SAFE_FILENAME, &type);
147 if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
148 {
149 checkFileData(UNSAFE_FILENAME);
150 }
151
152 initFile(SAFE_FILENAME);
153 initFile(UNSAFE_FILENAME);
154
155 rc = NANDSimpleSafeOpen(SAFE_FILENAME, &safeInfo, NAND_ACCESS_RW, copyBuf, COPYBUF_SIZE);
156 if(rc != NAND_RESULT_OK)
157 {
158 printErrMsg(rc);
159 OSHalt("Unexpected error.");
160 }
161
162 rc = NANDOpen(UNSAFE_FILENAME, &unsafeInfo, NAND_ACCESS_RW);
163 if(rc != NAND_RESULT_OK)
164 {
165 printErrMsg(rc);
166 OSHalt("Unexpected error.");
167 }
168
169 // First write
170 rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
171 if(rc != FILE_SIZE/2)
172 {
173 printErrMsg(rc);
174 OSHalt("Unexpected error.");
175 }
176
177 // First write
178 rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
179 if(rc != FILE_SIZE/2)
180 {
181 printErrMsg(rc);
182 OSHalt("Unexpected error.");
183 }
184
185 OSReport("Wrote 'B' to both anterior half area.\n");
186
187 // This operation causes FAT commit.
188 rc = NANDCreate("/tmp/file.tmp", PERM, ATTR);
189 if(rc!=NAND_RESULT_OK)
190 {
191 printErrMsg(rc);
192 OSHalt("create tmp file failed.");
193 }
194
195 OSReport("Press A button to continue writing data.\n");
196 OSReport("Press START button to quit writing data.\n");
197 OSReport("After that, please execute this demo program again.\n");
198 while(1)
199 {
200 PADRead(pad);
201 if(pad[0].button & PAD_BUTTON_A)
202 {
203 break;
204 }
205 if(pad[0].button & PAD_BUTTON_START)
206 {
207 OSHalt("Program is terminated before closing files.");
208 }
209
210 VIWaitForRetrace();
211 }
212
213 // Second write
214 rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
215 if(rc != FILE_SIZE/2)
216 {
217 printErrMsg(rc);
218 OSHalt("Unexpected error.");
219 }
220
221 // Second write
222 rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
223 if(rc != FILE_SIZE/2)
224 {
225 printErrMsg(rc);
226 OSHalt("Unexpected error.");
227 }
228
229 OSReport("Wrote 'B' to both last half area.\n");
230
231 rc = NANDSimpleSafeClose(&safeInfo);
232 if(rc != NAND_RESULT_OK)
233 {
234 printErrMsg(rc);
235 OSHalt("Unexpected error.");
236 }
237
238 rc = NANDClose(&unsafeInfo);
239 if(rc != NAND_RESULT_OK)
240 {
241 printErrMsg(rc);
242 OSHalt("Unexpected error.");
243 }
244
245 OSHalt("Program completed normally.");
246 return 0;
247 }
248
249