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 | |
parent | f59f673a721cf833bafed0705d2db01cd1f358a7 (diff) | |
download | uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.tar.gz uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.zip |
Add incomplete filesystem prototype
Diffstat (limited to 'src')
-rw-r--r-- | src/filesystem.c | 118 | ||||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/text.h | 2 |
3 files changed, 139 insertions, 1 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 | } | ||
@@ -3,6 +3,7 @@ | |||
3 | #include "common.h" | 3 | #include "common.h" |
4 | #include "bitmap.h" | 4 | #include "bitmap.h" |
5 | #include "bd-font.c" | 5 | #include "bd-font.c" |
6 | #include "filesystem.c" | ||
6 | 7 | ||
7 | #include "uxn/uxn.h" | 8 | #include "uxn/uxn.h" |
8 | #include "uxn/uxn.c" | 9 | #include "uxn/uxn.c" |
@@ -266,6 +267,25 @@ int main(void) { | |||
266 | }, &ppu.fg); | 267 | }, &ppu.fg); |
267 | txt_position(0,0); | 268 | txt_position(0,0); |
268 | 269 | ||
270 | fs_init(); | ||
271 | |||
272 | // DEBUG:... | ||
273 | int file_idx; | ||
274 | if ((file_idx = fs_open_file("HELLO_FILE")) >= 0) { | ||
275 | fs_write("HEY", 3, file_idx, 0, false); | ||
276 | fs_write("THERE", 3, file_idx, 1, true); | ||
277 | txt_printf("nam: %s\n", filesystem.files[file_idx].name); | ||
278 | txt_printf("num: %d\n", filesystem.num_files); | ||
279 | txt_printf("size: %d\n", filesystem.files[file_idx].size); | ||
280 | } | ||
281 | if ((file_idx = fs_open_file("HELLO_FOLKS")) >= 0) { | ||
282 | fs_write("BY GOD", 6, file_idx, 0, false); | ||
283 | fs_write("XXX", 3, file_idx, 1, true); | ||
284 | txt_printf("nam: %s\n", filesystem.files[file_idx].name); | ||
285 | txt_printf("num: %d\n", filesystem.num_files); | ||
286 | txt_printf("size: %d\n", filesystem.files[file_idx].size); | ||
287 | } | ||
288 | |||
269 | // Main loop. | 289 | // Main loop. |
270 | int frame_counter = 0; | 290 | int frame_counter = 0; |
271 | evaluxn(&u, 0x0100); | 291 | evaluxn(&u, 0x0100); |
@@ -132,7 +132,7 @@ txt_putc_hybrid(char c) { | |||
132 | int x = text_engine.cursor_x; | 132 | int x = text_engine.cursor_x; |
133 | int y = text_engine.cursor_y; | 133 | int y = text_engine.cursor_y; |
134 | Tile *buf = text_engine.memory; | 134 | Tile *buf = text_engine.memory; |
135 | buf[x + y * 30] = tile; | 135 | buf[x + y * 32] = tile; |
136 | dirty_tiles[y] |= 1 << x; | 136 | dirty_tiles[y] |= 1 << x; |
137 | text_engine.cursor_x += 1; | 137 | text_engine.cursor_x += 1; |
138 | if (text_engine.cursor_x >= 30) { | 138 | if (text_engine.cursor_x >= 30) { |