aboutsummaryrefslogtreecommitdiffstats
path: root/src/filesystem.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-21 17:17:52 +0200
committerBad Diode <bd@badd10de.dev>2021-05-21 17:17:52 +0200
commitaf98fa608fb4ba98138e2b1239f173e6d74d6d86 (patch)
tree90fbdb03c81a61fef396cc22efcf3c1e2c2fdacd /src/filesystem.c
parentf59f673a721cf833bafed0705d2db01cd1f358a7 (diff)
downloaduxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.tar.gz
uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.zip
Add incomplete filesystem prototype
Diffstat (limited to 'src/filesystem.c')
-rw-r--r--src/filesystem.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/filesystem.c b/src/filesystem.c
new file mode 100644
index 0000000..2da77be
--- /dev/null
+++ b/src/filesystem.c
@@ -0,0 +1,118 @@
1// We need 64 * 32 bytes (2K) of SRAM for file indexes. To avoid corruption
2// issues we ignore the first file (32 bytes).
3// Note that the filename should include the null terminator if we want to use
4// strcmp.
5#define FILE_NAME_SIZE 27
6#define FILE_CAPACITY 63
7#define FILE_HEADER_OFFSET 2
8#define FILE_INDEX_OFFSET 32
9#define FILE_DATA_OFFSET KB(2)
10#define FILE_MAX_SIZE KB(1)
11#define SRAM ((vu8*)(MEM_CART))
12
13typedef struct File {
14 char name[FILE_NAME_SIZE + 1];
15 u16 size;
16 u16 mem_offset; // NOTE: Unused...
17} File;
18
19// The filesystem header.
20typedef struct FileSystem {
21 u16 num_files;
22 u16 data_size; // NOTE: Unused...
23 u16 data_capacity; // NOTE: Unused...
24 File files[FILE_CAPACITY];
25} FileSystem;
26
27static FileSystem filesystem;
28
29void
30_fs_read(u8 *dst, size_t pos, size_t n_bytes) {
31 for (size_t i = 0; i < n_bytes; ++i) {
32 dst[i] = SRAM[pos + i];
33 }
34}
35
36void
37_fs_write(u8 *src, size_t pos, size_t n_bytes) {
38 for (size_t i = 0; i < n_bytes; ++i) {
39 SRAM[pos + i] = src[i];
40 }
41}
42
43void
44fs_init() {
45 // Load header if existing.
46 _fs_read(&filesystem, FILE_HEADER_OFFSET, offsetof(FileSystem, files));
47 if (filesystem.num_files == 0xFFFF
48 && filesystem.data_capacity == 0xFFFF
49 && filesystem.data_size == 0xFFFF) {
50 filesystem.num_files = 0;
51 filesystem.data_size = 0;
52 filesystem.data_capacity = 27 * FILE_MAX_SIZE;
53 memset(&filesystem.files, 0, FILE_CAPACITY * sizeof(File));
54 _fs_write(&filesystem, FILE_HEADER_OFFSET, offsetof(FileSystem, files));
55 } else {
56 _fs_read(&filesystem.files, FILE_INDEX_OFFSET, sizeof(File) * filesystem.num_files);
57 }
58}
59
60int
61fs_open_file(char *name) {
62 // Try to find an existing file.
63 for (size_t i = 0; i < filesystem.num_files; ++i) {
64 // TODO: Replace strcmp with vectorized fixed size char comparison.
65 if (strcmp(name, filesystem.files[i].name) == 0) {
66 return i;
67 }
68 }
69 // Create a new file if there is space.
70 if (filesystem.num_files < FILE_CAPACITY) {
71 size_t index = filesystem.num_files++;
72 size_t k = 0;
73 while(*name) {
74 filesystem.files[index].name[k++] = *name++;
75 }
76 filesystem.files[index].size = 0;
77 filesystem.files[index].mem_offset = 0;
78
79 // Update file index.
80 _fs_write(&filesystem.files[index],
81 FILE_INDEX_OFFSET + index * sizeof(File),
82 sizeof(File));
83
84 // Update header.
85 _fs_write(&filesystem, FILE_HEADER_OFFSET, offsetof(FileSystem, files));
86
87 return index;
88 }
89 return -1;
90}
91
92int
93fs_write(u8 *src, size_t n_bytes, u16 file_index, u16 offset, bool append) {
94 File *file = &filesystem.files[file_index];
95
96 // Check if there is enough capacity for this write operation.
97 if (offset + n_bytes >= FILE_MAX_SIZE) {
98 return -1;
99 }
100
101 // Write data to file block.
102 _fs_write(src, FILE_DATA_OFFSET + FILE_MAX_SIZE * file_index + offset, n_bytes);
103
104 // Update file index.
105 if (append) {
106 if (offset + n_bytes > file->size) {
107 file->size = offset + n_bytes;
108 }
109 } else {
110 file->size = offset + n_bytes;
111 }
112 _fs_write(file, FILE_INDEX_OFFSET + file_index * sizeof(File), sizeof(File));
113
114 // Update header.
115 _fs_write(&filesystem, FILE_HEADER_OFFSET, offsetof(FileSystem, files));
116
117 return n_bytes;
118}