diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-21 17:17:52 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-21 17:17:52 +0200 |
commit | af98fa608fb4ba98138e2b1239f173e6d74d6d86 (patch) | |
tree | 90fbdb03c81a61fef396cc22efcf3c1e2c2fdacd /src/filesystem.c | |
parent | f59f673a721cf833bafed0705d2db01cd1f358a7 (diff) | |
download | uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.tar.gz uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.zip |
Add incomplete filesystem prototype
Diffstat (limited to 'src/filesystem.c')
-rw-r--r-- | src/filesystem.c | 118 |
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 | |||
13 | typedef 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. | ||
20 | typedef 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 | |||
27 | static FileSystem filesystem; | ||
28 | |||
29 | void | ||
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 | |||
36 | void | ||
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 | |||
43 | void | ||
44 | fs_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 | |||
60 | int | ||
61 | fs_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 | |||
92 | int | ||
93 | fs_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 | } | ||