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