aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parentf59f673a721cf833bafed0705d2db01cd1f358a7 (diff)
downloaduxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.tar.gz
uxngba-af98fa608fb4ba98138e2b1239f173e6d74d6d86.zip
Add incomplete filesystem prototype
Diffstat (limited to 'src')
-rw-r--r--src/filesystem.c118
-rw-r--r--src/main.c20
-rw-r--r--src/text.h2
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
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}
diff --git a/src/main.c b/src/main.c
index 6f5034b..798dc18 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/text.h b/src/text.h
index 1142a73..06e3973 100644
--- a/src/text.h
+++ b/src/text.h
@@ -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) {