KallistiOS
2.0.0
Main Page
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
kernel
arch
dreamcast
include
dc
vmufs.h
Go to the documentation of this file.
1
/* KallistiOS 2.0.0
2
3
dc/vmufs.h
4
Copyright (C) 2003 Dan Potter
5
6
*/
7
8
/** \file dc/vmufs.h
9
\brief Low-level VMU filesystem driver.
10
11
The VMU filesystem driver mounts itself on /vmu of the VFS. Each memory card
12
has its own subdirectory off of that directory (i.e, /vmu/a1 for slot 1 of
13
the first controller). VMUs themselves have no subdirectories, so the driver
14
itself is fairly simple.
15
16
Files on a VMU must be multiples of 512 bytes in size, and should have a
17
header attached so that they show up in the BIOS menu.
18
19
\author Dan Potter
20
\see dc/vmu_pkg.h
21
\see dc/fs_vmu.h
22
*/
23
24
#ifndef __DC_VMUFS_H
25
#define __DC_VMUFS_H
26
27
#include <sys/cdefs.h>
28
__BEGIN_DECLS
29
30
#include <
dc/maple.h
>
31
32
/* \cond */
33
#define __packed__ __attribute__((packed))
34
/* \endcond */
35
36
/** \brief BCD timestamp, used several places in the vmufs.
37
\headerfile dc/vmufs.h
38
*/
39
typedef
struct
{
40
uint8
cent
;
/**< \brief Century */
41
uint8
year
;
/**< \brief Year, within century */
42
uint8
month
;
/**< \brief Month of the year */
43
uint8
day
;
/**< \brief Day of the month */
44
uint8
hour
;
/**< \brief Hour of the day */
45
uint8
min
;
/**< \brief Minutes */
46
uint8
sec
;
/**< \brief Seconds */
47
uint8
dow
;
/**< \brief Day of week (0 = monday, etc) */
48
} __packed__
vmu_timestamp_t
;
49
50
/** \brief VMU FS Root block layout.
51
\headerfile dc/vmufs.h
52
*/
53
typedef
struct
{
54
uint8
magic[16];
/**< \brief All should contain 0x55 */
55
uint8
use_custom
;
/**< \brief 0 = standard, 1 = custom */
56
uint8
custom_color[4];
/**< \brief blue, green, red, alpha */
57
uint8
pad1[27];
/**< \brief All zeros */
58
vmu_timestamp_t
timestamp
;
/**< \brief BCD timestamp */
59
uint8
pad2[8];
/**< \brief All zeros */
60
uint8
unk1[6];
/**< \brief ??? */
61
uint16
fat_loc
;
/**< \brief FAT location */
62
uint16
fat_size
;
/**< \brief FAT size in blocks */
63
uint16
dir_loc
;
/**< \brief Directory location */
64
uint16
dir_size
;
/**< \brief Directory size in blocks */
65
uint16
icon_shape
;
/**< \brief Icon shape for this VMS */
66
uint16
blk_cnt
;
/**< \brief Number of user blocks */
67
uint8
unk2[430];
/**< \brief ??? */
68
} __packed__
vmu_root_t
;
69
70
/** \brief VMU FS Directory entries, 32 bytes each.
71
\headerfile dc/vmufs.h
72
*/
73
typedef
struct
{
74
uint8
filetype
;
/**< \brief 0x00 = no file; 0x33 = data; 0xcc = a game */
75
uint8
copyprotect
;
/**< \brief 0x00 = copyable; 0xff = copy protected */
76
uint16
firstblk
;
/**< \brief Location of the first block in the file */
77
char
filename[12];
/**< \brief Note: there is no null terminator */
78
vmu_timestamp_t
timestamp
;
/**< \brief File time */
79
uint16
filesize
;
/**< \brief Size of the file in blocks */
80
uint16
hdroff
;
/**< \brief Offset of header, in blocks from start of file */
81
uint8
dirty
;
/**< \brief See header notes */
82
uint8
pad1[3];
/**< \brief All zeros */
83
} __packed__
vmu_dir_t
;
84
#undef __packed__
85
86
/* Notes about the "dirty" field on vmu_dir_t :)
87
88
This byte should always be zero when written out to the VMU. What this
89
lets us do, though, is conserve on flash writes. If you only want to
90
modify one single file (which is the standard case) then re-writing all
91
of the dir blocks is a big waste. Instead, you should set the dirty flag
92
on the in-mem copy of the directory, and writing it back out will only
93
flush the containing block back to the VMU, setting it back to zero
94
in the process. Loaded blocks should always have zero here (though we
95
enforce that in the code to make sure) so it will be non-dirty by
96
default.
97
*/
98
99
100
/* ****************** Low level functions ******************** */
101
102
/** \brief Fill in the date on a vmu_dir_t for writing.
103
104
\param d The directory to fill in the date on.
105
*/
106
void
vmufs_dir_fill_time
(
vmu_dir_t
*d);
107
108
/** \brief Reads a selected VMU's root block.
109
110
This function assumes the mutex is held.
111
112
\param dev The VMU to read from.
113
\param root_buf A buffer to hold the root block. You must allocate
114
this yourself before calling.
115
\retval -1 On failure.
116
\retval 0 On success.
117
*/
118
int
vmufs_root_read
(
maple_device_t
* dev,
vmu_root_t
* root_buf);
119
120
/** \brief Writes a selected VMU's root block.
121
122
This function assumes the mutex is held.
123
124
\param dev The VMU to write to.
125
\param root_buf The root block to write.
126
\retval -1 On failure.
127
\retval 0 On success.
128
*/
129
int
vmufs_root_write
(
maple_device_t
* dev,
vmu_root_t
* root_buf);
130
131
/** \brief Given a VMU's root block, return the amount of space in bytes
132
required to hold its directory.
133
134
\param root_buf The root block to check.
135
\return The amount of space, in bytes, needed.
136
*/
137
int
vmufs_dir_blocks
(
vmu_root_t
* root_buf);
138
139
/** \brief Given a VMU's root block, return the amount of space in bytes
140
required to hold its FAT.
141
142
\param root_buf The root block to check.
143
\return The amount of space, in bytes, needed.
144
*/
145
int
vmufs_fat_blocks
(
vmu_root_t
* root_buf);
146
147
/** \brief Given a selected VMU's root block, read its directory.
148
149
This function reads the directory of a given VMU root block. It assumes the
150
mutex is held. There must be at least the number of bytes returned by
151
vmufs_dir_blocks() available in the buffer for this to succeed.
152
153
\param dev The VMU to read.
154
\param root_buf The VMU's root block.
155
\param dir_buf The buffer to hold the directory. You must have
156
allocated this yourself.
157
\return 0 on success, <0 on failure.
158
*/
159
int
vmufs_dir_read
(
maple_device_t
* dev,
vmu_root_t
* root_buf,
160
vmu_dir_t
* dir_buf);
161
162
/** \brief Given a selected VMU's root block and dir blocks, write the dirty
163
dir blocks back to the VMU. Assumes the mutex is held.
164
165
\param dev The VMU to write to.
166
\param root The VMU's root block.
167
\param dir_buf The VMU's directory structure.
168
\return 0 on success, <0 on failure.
169
*/
170
int
vmufs_dir_write
(
maple_device_t
* dev,
vmu_root_t
* root,
171
vmu_dir_t
* dir_buf);
172
173
/** \brief Given a selected VMU's root block, read its FAT.
174
175
This function reads the FAT of a VMU, given its root block. It assumes the
176
mutex is held. There must be at least the number of bytes returned by
177
vmufs_fat_blocks() available in the buffer for this to succeed.
178
179
\param dev The VMU to read from.
180
\param root The VMU's root block.
181
\param fat_buf The buffer to store the FAT into. You must
182
pre-allocate this.
183
\return 0 on success, <0 on failure.
184
*/
185
int
vmufs_fat_read
(
maple_device_t
* dev,
vmu_root_t
* root,
uint16
* fat_buf);
186
187
/** \brief Given a selected VMU's root block and its FAT, write the FAT blocks
188
back to the VMU.
189
190
This function assumes the mutex is held.
191
192
\param dev The VMU to write to.
193
\param root The VMU's root block.
194
\param fat_buf The buffer to write to the FAT.
195
\return 0 on success, <0 on failure.
196
*/
197
int
vmufs_fat_write
(
maple_device_t
* dev,
vmu_root_t
* root,
uint16
* fat_buf);
198
199
/** \brief Given a previously-read directory, locate a file by filename.
200
201
\param root The VMU root block.
202
\param dir The VMU directory.
203
\param fn The file to find (only checked up to 12 chars).
204
\return The index into the directory array on success, or
205
<0 on failure.
206
*/
207
int
vmufs_dir_find
(
vmu_root_t
* root,
vmu_dir_t
* dir,
const
char
* fn);
208
209
/** \brief Given a previously-read directory, add a new dirent to the dir.
210
211
Another file with the same name should not exist (delete it first if it
212
does). This function will not check for dupes!
213
214
\param root The VMU root block.
215
\param dir The VMU directory.
216
\param newdirent The new entry to add.
217
\return 0 on success, or <0 on failure. */
218
int
vmufs_dir_add
(
vmu_root_t
* root,
vmu_dir_t
* dir,
vmu_dir_t
* newdirent);
219
220
/** \brief Given a pointer to a directory struct and a previously loaded FAT,
221
load the indicated file from the VMU.
222
223
An appropriate amount of space must have been allocated previously in the
224
buffer. Assumes the mutex is held.
225
226
\param dev The VMU to read from.
227
\param fat The FAT of the VMU.
228
\param dirent The entry to read.
229
\param outbuf A buffer to write the data into. You must allocate
230
this yourself with the appropriate amount of space.
231
\return 0 on success, <0 on failure.
232
*/
233
int
vmufs_file_read
(
maple_device_t
* dev,
uint16
* fat,
vmu_dir_t
*
dirent
,
void
* outbuf);
234
235
/** \brief Given a pointer to a mostly-filled directory struct and a previously
236
loaded directory and FAT, write the indicated file to the VMU.
237
238
The named file should not exist in the directory already. The directory and
239
FAT will _not_ be sync'd back to the VMU, this must be done manually.
240
Assumes the mutex is held.
241
242
\param dev The VMU to write to.
243
\param root The VMU root block.
244
\param fat The FAT of the VMU.
245
\param dir The directory of the VMU.
246
\param newdirent The new entry to write.
247
\param filebuf The new file data.
248
\param size The size of the file in blocks (512-bytes each).
249
\return 0 on success, <0 on failure.
250
*/
251
int
vmufs_file_write
(
maple_device_t
* dev,
vmu_root_t
* root,
uint16
* fat,
252
vmu_dir_t
* dir,
vmu_dir_t
* newdirent,
void
* filebuf,
int
size);
253
254
/** \brief Given a previously-read FAT and directory, delete the named file.
255
256
No changes are made to the VMU itself, just the in-memory structs.
257
258
\param root The VMU root block.
259
\param fat The FAT to be modified.
260
\param dir The directory to be modified.
261
\param fn The file name to be deleted.
262
\retval 0 On success.
263
\retval -1 If fn is not found.
264
*/
265
int
vmufs_file_delete
(
vmu_root_t
* root,
uint16
* fat,
vmu_dir_t
* dir,
const
char
*fn);
266
267
/** \brief Given a previously-read FAT, return the number of blocks available
268
to write out new file data.
269
270
\param root The VMU root block.
271
\param fat The FAT to be examined.
272
\return The number of blocks available.
273
*/
274
int
vmufs_fat_free
(
vmu_root_t
* root,
uint16
* fat);
275
276
/** \brief Given a previously-read directory, return the number of dirents
277
available for new files.
278
279
\param root The VMU root block.
280
\param dir The directory in question.
281
\return The number of entries available.
282
*/
283
int
vmufs_dir_free
(
vmu_root_t
* root,
vmu_dir_t
* dir);
284
285
/** \brief Lock the vmufs mutex.
286
287
This should be done before you attempt any low-level ops.
288
289
\retval 0 On success (no error conditions defined).
290
*/
291
int
vmufs_mutex_lock
();
292
293
/** \brief Unlock the vmufs mutex.
294
295
This should be done once you're done with any low-level ops.
296
297
\retval 0 On success (no error conditions defined).
298
*/
299
int
vmufs_mutex_unlock
();
300
301
302
/* ****************** Higher level functions ******************** */
303
304
/** \brief Read the directory from a VMU.
305
306
The output buffer will be allocated for you using malloc(), and the number
307
of entries will be returned. On failure, outbuf will not contain a dangling
308
buffer that needs to be freed (no further action required).
309
310
\param dev The VMU to read from.
311
\param outbuf A buffer that will be allocated where the directory
312
data will be placed.
313
\param outcnt The number of entries in outbuf.
314
\return 0 on success, or <0 on failure. */
315
int
vmufs_readdir
(
maple_device_t
* dev,
vmu_dir_t
** outbuf,
int
* outcnt);
316
317
/** \brief Read a file from the VMU.
318
319
The output buffer will be allocated for you using malloc(), and the size of
320
the file will be returned. On failure, outbuf will not contain a dangling
321
buffer that needs to be freed (no further action required).
322
323
\param dev The VMU to read from.
324
\param fn The name of the file to read.
325
\param outbuf A buffer that will be allocated where the file data
326
will be placed.
327
\param outsize Storage for the size of the file, in bytes.
328
\return 0 on success, or <0 on failure.
329
*/
330
int
vmufs_read
(
maple_device_t
* dev,
const
char
* fn,
void
** outbuf,
int
* outsize);
331
332
/** \brief Read a file from the VMU, using a pre-read dirent.
333
334
This function is faster to use than vmufs_read() if you already have done
335
the lookup, since it won't need to do that.
336
337
\param dev The VMU to read from.
338
\param dirent The entry to read.
339
\param outbuf A buffer that will be allocated where the file data
340
will be placed.
341
\param outsize Storage for the size of the file, in bytes.
342
\return 0 on success, <0 on failure.
343
*/
344
int
vmufs_read_dirent
(
maple_device_t
* dev,
vmu_dir_t
*
dirent
,
void
** outbuf,
int
* outsize);
345
346
/* Flags for vmufs_write */
347
#define VMUFS_OVERWRITE 1
/**< \brief Overwrite existing files */
348
#define VMUFS_VMUGAME 2
/**< \brief This file is a VMU game */
349
#define VMUFS_NOCOPY 4
/**< \brief Set the no-copy flag */
350
351
/** \brief Write a file to the VMU.
352
353
If the named file already exists, then the function checks 'flags'. If
354
VMUFS_OVERWRITE is set, then the old file is deleted first before the new
355
one is written (this all happens atomically). On partial failure, some data
356
blocks may have been written, but in general the card should not be damaged.
357
358
\param dev The VMU to write to.
359
\param fn The filename to write.
360
\param inbuf The data to write to the file.
361
\param insize The size of the file in bytes.
362
\param flags Flags for the write (i.e, VMUFS_OVERWRITE,
363
VMUFS_VMUGAME, VMUFS_NOCOPY).
364
\return 0 on success, or <0 for failure.
365
*/
366
int
vmufs_write
(
maple_device_t
* dev,
const
char
* fn,
void
* inbuf,
int
insize,
int
flags);
367
368
/** \brief Delete a file from the VMU.
369
370
\retval 0 On success.
371
\retval -1 If the file is not found.
372
\retval -2 On other failure.
373
*/
374
int
vmufs_delete
(
maple_device_t
* dev,
const
char
* fn);
375
376
/** \brief Return the number of user blocks free for file writing.
377
378
You should check this number before attempting to write.
379
380
\return The number of blocks free for writing.
381
*/
382
int
vmufs_free_blocks
(
maple_device_t
* dev);
383
384
385
/** \brief Initialize vmufs.
386
387
Must be called before anything else is useful.
388
389
\retval 0 On success (no error conditions defined).
390
*/
391
int
vmufs_init
();
392
393
/** \brief Shutdown vmufs.
394
395
Must be called after everything is finished.
396
*/
397
int
vmufs_shutdown
();
398
399
__END_DECLS
400
401
#endif
/* __DC_VMUFS_H */
Generated by
1.8.1.1