aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-03-15 20:15:47 +0100
committerBad Diode <bd@badd10de.dev>2022-03-15 20:15:47 +0100
commit42ff1ee0915032819d769a16bd0048f11366d465 (patch)
tree499ac670e408de96a53f2ea43e79aaa93516f8f2 /src
parent2d072d0d8f72c710ef10f620a9b2c9be604826a7 (diff)
downloaduxngba-42ff1ee0915032819d769a16bd0048f11366d465.tar.gz
uxngba-42ff1ee0915032819d769a16bd0048f11366d465.zip
Add initial version of updated file device
Diffstat (limited to 'src')
-rw-r--r--src/file.c83
-rw-r--r--src/main.c58
2 files changed, 122 insertions, 19 deletions
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..a45d59f
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,83 @@
1/*
2Copyright (c) 2021 Devine Lu Linvega
3Copyright (c) 2021 Andrew Alderwick
4Copyright (c) 2022 Bad Diode
5
6Permission to use, copy, modify, and distribute this software for any
7purpose with or without fee is hereby granted, provided that the above
8copyright notice and this permission notice appear in all copies.
9
10THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11WITH REGARD TO THIS SOFTWARE.
12*/
13
14#include "posprintf.h"
15
16static File f = {0};
17static char *current_filename = "";
18
19static enum {
20 IDLE,
21 FILE_READ,
22 FILE_WRITE,
23} file_state;
24
25void
26file_reset(void) {
27 f = (File){0};
28 file_state = IDLE;
29}
30
31u16
32file_init(void *filename) {
33 file_reset();
34 current_filename = filename;
35 return 0;
36}
37
38u16
39file_read(void *dest, u16 len) {
40 if(file_state != FILE_READ) {
41 file_reset();
42 f = fs_open_file(current_filename, FS_OPEN_READ);
43 file_state = FILE_READ;
44 }
45 if (f.index == FS_NULL) {
46 return 0;
47 }
48 return fs_read(dest, len, &f);
49}
50
51u16
52file_write(void *src, u16 len, u8 flags) {
53 if(file_state != FILE_WRITE) {
54 file_reset();
55 OpenMode mode = (flags & 0x01) ? FS_OPEN_APPEND : FS_OPEN_WRITE;
56 f = fs_open_file(current_filename, mode);
57 file_state = FILE_WRITE;
58 }
59 if (f.index == FS_NULL) {
60 return 0;
61 }
62 return fs_write(src, len, &f);
63}
64
65u16
66file_stat(void *dest, u16 len) {
67 if(len < strlen(current_filename) + 7) {
68 return 0;
69 }
70 if (f.index == FS_NULL) {
71 posprintf(dest, "!!!! %s\n", current_filename);
72 } else {
73 u16 file_size = fs_file_size(&f);
74 posprintf(dest, "%04x %s\n", (unsigned int)file_size, current_filename);
75 }
76 return 0;
77}
78
79// static u16
80// file_delete(void)
81// {
82// return unlink(current_filename);
83// }
diff --git a/src/main.c b/src/main.c
index 296373f..c3a1115 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,6 +20,7 @@ WITH REGARD TO THIS SOFTWARE.
20#include "uxn.c" 20#include "uxn.c"
21#include "ppu.c" 21#include "ppu.c"
22#include "apu.c" 22#include "apu.c"
23#include "file.c"
23#include "text.h" 24#include "text.h"
24 25
25// 26//
@@ -220,27 +221,46 @@ datetime_talk(Device *d, u8 b0, u8 w) {
220 221
221void 222void
222file_talk(Device *d, u8 b0, u8 w) { 223file_talk(Device *d, u8 b0, u8 w) {
223 u8 read = b0 == 0xd; 224 if (w) {
224 if(w && (read || b0 == 0xf)) { 225 u16 a, b, res;
225 char *name = (char *)&d->mem[mempeek16(d->dat, 0x8)]; 226 switch(b0) {
226 u16 result = 0, length = mempeek16(d->dat, 0xa); 227 case 0x5: {
227 u16 offset = mempeek16(d->dat, 0x4); 228 DEVPEEK16(a, 0x4);
228 u16 addr = mempeek16(d->dat, b0 - 1); 229 DEVPEEK16(b, 0xa);
229 OpenMode mode = FS_OPEN_READ; 230 if(b > 0x10000 - a) {
230 if (!read) { 231 b = 0x10000 - a;
231 mode = offset ? FS_OPEN_APPEND : FS_OPEN_WRITE;
232 }
233 File file = fs_open_file(name, mode);
234 if (file.index != FS_NULL) {
235 if(fs_seek(&file, offset, SEEK_SET) != -1) {
236 if (read) {
237 result = fs_read(&d->mem[addr], length, &file);
238 } else {
239 result = fs_write(&d->mem[addr], length, &file);
240 } 232 }
241 } 233 res = file_stat(&d->mem[a], b);
234 DEVPOKE16(0x2, res);
235 } break;
236 case 0x6: {
237 // res = file_delete();
238 // DEVPOKE16(0x2, res);
239 } break;
240 case 0x9: {
241 DEVPEEK16(a, 0x8);
242 res = file_init(&d->mem[a]);
243 DEVPOKE16(0x2, res);
244 } break;
245 case 0xd: {
246 DEVPEEK16(a, 0xc);
247 DEVPEEK16(b, 0xa);
248 if(b > 0x10000 - a) {
249 b = 0x10000 - a;
250 }
251 res = file_read(&d->mem[a], b);
252 DEVPOKE16(0x2, res);
253 } break;
254 case 0xf: {
255 DEVPEEK16(a, 0xe);
256 DEVPEEK16(b, 0xa);
257 if(b > 0x10000 - a) {
258 b = 0x10000 - a;
259 }
260 res = file_write(&d->mem[a], b, d->dat[0x7]);
261 DEVPOKE16(0x2, res);
262 } break;
242 } 263 }
243 mempoke16(d->dat, 0x2, result);
244 } 264 }
245} 265}
246 266