From 42ff1ee0915032819d769a16bd0048f11366d465 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 15 Mar 2022 20:15:47 +0100 Subject: Add initial version of updated file device --- src/file.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 58 +++++++++++++++++++++++++++++-------------- 2 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 src/file.c (limited to 'src') 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 @@ +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick +Copyright (c) 2022 Bad Diode + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +#include "posprintf.h" + +static File f = {0}; +static char *current_filename = ""; + +static enum { + IDLE, + FILE_READ, + FILE_WRITE, +} file_state; + +void +file_reset(void) { + f = (File){0}; + file_state = IDLE; +} + +u16 +file_init(void *filename) { + file_reset(); + current_filename = filename; + return 0; +} + +u16 +file_read(void *dest, u16 len) { + if(file_state != FILE_READ) { + file_reset(); + f = fs_open_file(current_filename, FS_OPEN_READ); + file_state = FILE_READ; + } + if (f.index == FS_NULL) { + return 0; + } + return fs_read(dest, len, &f); +} + +u16 +file_write(void *src, u16 len, u8 flags) { + if(file_state != FILE_WRITE) { + file_reset(); + OpenMode mode = (flags & 0x01) ? FS_OPEN_APPEND : FS_OPEN_WRITE; + f = fs_open_file(current_filename, mode); + file_state = FILE_WRITE; + } + if (f.index == FS_NULL) { + return 0; + } + return fs_write(src, len, &f); +} + +u16 +file_stat(void *dest, u16 len) { + if(len < strlen(current_filename) + 7) { + return 0; + } + if (f.index == FS_NULL) { + posprintf(dest, "!!!! %s\n", current_filename); + } else { + u16 file_size = fs_file_size(&f); + posprintf(dest, "%04x %s\n", (unsigned int)file_size, current_filename); + } + return 0; +} + +// static u16 +// file_delete(void) +// { +// return unlink(current_filename); +// } 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. #include "uxn.c" #include "ppu.c" #include "apu.c" +#include "file.c" #include "text.h" // @@ -220,27 +221,46 @@ datetime_talk(Device *d, u8 b0, u8 w) { void file_talk(Device *d, u8 b0, u8 w) { - u8 read = b0 == 0xd; - if(w && (read || b0 == 0xf)) { - char *name = (char *)&d->mem[mempeek16(d->dat, 0x8)]; - u16 result = 0, length = mempeek16(d->dat, 0xa); - u16 offset = mempeek16(d->dat, 0x4); - u16 addr = mempeek16(d->dat, b0 - 1); - OpenMode mode = FS_OPEN_READ; - if (!read) { - mode = offset ? FS_OPEN_APPEND : FS_OPEN_WRITE; - } - File file = fs_open_file(name, mode); - if (file.index != FS_NULL) { - if(fs_seek(&file, offset, SEEK_SET) != -1) { - if (read) { - result = fs_read(&d->mem[addr], length, &file); - } else { - result = fs_write(&d->mem[addr], length, &file); + if (w) { + u16 a, b, res; + switch(b0) { + case 0x5: { + DEVPEEK16(a, 0x4); + DEVPEEK16(b, 0xa); + if(b > 0x10000 - a) { + b = 0x10000 - a; } - } + res = file_stat(&d->mem[a], b); + DEVPOKE16(0x2, res); + } break; + case 0x6: { + // res = file_delete(); + // DEVPOKE16(0x2, res); + } break; + case 0x9: { + DEVPEEK16(a, 0x8); + res = file_init(&d->mem[a]); + DEVPOKE16(0x2, res); + } break; + case 0xd: { + DEVPEEK16(a, 0xc); + DEVPEEK16(b, 0xa); + if(b > 0x10000 - a) { + b = 0x10000 - a; + } + res = file_read(&d->mem[a], b); + DEVPOKE16(0x2, res); + } break; + case 0xf: { + DEVPEEK16(a, 0xe); + DEVPEEK16(b, 0xa); + if(b > 0x10000 - a) { + b = 0x10000 - a; + } + res = file_write(&d->mem[a], b, d->dat[0x7]); + DEVPOKE16(0x2, res); + } break; } - mempoke16(d->dat, 0x2, result); } } -- cgit v1.2.1