From 8e64a8a1074529b099a5619012c03411f4dcbfe7 Mon Sep 17 00:00:00 2001 From: Lephe Date: Sun, 6 Apr 2025 15:49:43 +0200 Subject: [PATCH] fs: fx-CP 400 fixes, still unreliable when writing as previously known --- src/fs/fugue/fugue_mkdir.c | 21 +++++++++++---------- src/fs/fugue/fugue_open.c | 12 ++++++++---- src/fs/fugue/fugue_unlink.c | 31 +++++++++++++++++++++++-------- src/fs/fugue/util.c | 32 ++++++++++++++++++++++++-------- src/fs/fugue/util.h | 3 +++ src/kernel/hardware.c | 3 +-- src/kernel/syscalls.S | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/fs/fugue/fugue_mkdir.c b/src/fs/fugue/fugue_mkdir.c index 5dba72e..57e139f 100644 --- a/src/fs/fugue/fugue_mkdir.c +++ b/src/fs/fugue/fugue_mkdir.c @@ -10,12 +10,14 @@ int fugue_mkdir(char const *path, GUNUSED mode_t mode) ENOTSUP_IF_NOT_FUGUE(-1); #if GINT_OS_CP - int rc = BFile_Mkdir(path); - if(rc < 0) { - errno = bfile_error_to_errno(rc); + char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\'); + if(!normpath) { + errno = ENOMEM; return -1; } - return 0; + + int rc = BFile_Mkdir(normpath); + free(normpath); #else uint16_t *fcpath = fs_path_normalize_fc(path); if(!fcpath) { @@ -24,13 +26,12 @@ int fugue_mkdir(char const *path, GUNUSED mode_t mode) } int rc = BFile_Create(fcpath, BFile_Folder, NULL); + free(fcpath); +#endif + if(rc < 0) { errno = bfile_error_to_errno(rc); - free(fcpath); - return -1; + rc = -1; } - - free(fcpath); - return 0; -#endif + return rc; } diff --git a/src/fs/fugue/fugue_open.c b/src/fs/fugue/fugue_open.c index 2599c7f..5f7047f 100644 --- a/src/fs/fugue/fugue_open.c +++ b/src/fs/fugue/fugue_open.c @@ -22,15 +22,15 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode) } #if GINT_OS_CP - char *normpath = fs_path_normalize(path); + char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\'); if(!normpath) { errno = ENOMEM; free(fcpath); return -1; } -#define NORMALIZED_PATH normpath +# define NORMALIZED_PATH normpath #else -#define NORMALIZED_PATH fcpath +# define NORMALIZED_PATH fcpath #endif /* Open mode */ @@ -48,7 +48,11 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode) respond well. fs_path_normalize_fc() normalizes the path so we just have to check for the fixed string "\\fls0\". */ bool exists; +#if GINT_OS_CP + if(!memcmp(fcpath, u"\\fls0\\", 14)) { +#else if(!memcmp(fcpath, u"\\\\fls0\\", 16)) { +#endif exists = true; type = BFile_Type_Directory; } @@ -127,7 +131,7 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode) if(fugue_fd < 0) { errno = bfile_error_to_errno(fugue_fd); - rc = fugue_fd; + rc = -1; goto end; } diff --git a/src/fs/fugue/fugue_unlink.c b/src/fs/fugue/fugue_unlink.c index be51a98..eb23375 100644 --- a/src/fs/fugue/fugue_unlink.c +++ b/src/fs/fugue/fugue_unlink.c @@ -16,29 +16,44 @@ int fugue_unlink(char const *path) return -1; } +#if GINT_OS_CP + char *normpath = fs_path_normalize_opt(path, "\\fls0\\", '\\'); + if(!normpath) { + errno = ENOMEM; + free(fcpath); + return -1; + } +#endif + int type, size, rc; rc = BFile_Ext_Stat(fcpath, &type, &size); if(rc < 0) { errno = bfile_error_to_errno(rc); - free(fcpath); - return -1; + rc = -1; + goto end; } if(bfile_type_to_mode_t(type) != S_IFREG) { errno = ENOTDIR; - free(fcpath); - return -1; + rc = -1; + goto end; } #if GINT_OS_CP - rc = BFile_Remove(path); + rc = BFile_Remove(normpath); #else rc = BFile_Remove(fcpath); #endif - free(fcpath); if(rc < 0) { errno = bfile_error_to_errno(rc); - return -1; + rc = -1; } - return 0; + rc = 0; + +end: + free(fcpath); +#if GINT_OS_CP + free(normpath); +#endif + return rc; } diff --git a/src/fs/fugue/util.c b/src/fs/fugue/util.c index b7131d2..747ab32 100644 --- a/src/fs/fugue/util.c +++ b/src/fs/fugue/util.c @@ -12,7 +12,7 @@ int bfile_error_to_errno(int e) { #if GINT_OS_CP switch(e) { - case BFileCP_ENOMEM: return ENOMEM; + case BFileCP_ENOMEM: return ENOENT; case BFileCP_EINVAL: return EINVAL; case BFileCP_EDEVFAIL: return EIO; case BFileCP_EMOUNTED: return ENODEV; @@ -206,8 +206,12 @@ char **fs_split_components(char *path, int *count) /* Generalization of fs_path_normalize(). Returns a [char *] if use_fc=false, otherwise returns an [uint16_t *]. */ -static void *path_normalize(char const *path, bool use_fc) +static void *path_normalize( + char const *path, bool use_fc, char const *prefix8, int dirsep) { + if(!prefix8) + prefix8 = "/"; + char *path_dup = strdup(path); if(!path_dup) return NULL; @@ -231,7 +235,8 @@ static void *path_normalize(char const *path, bool use_fc) } /* Count total length */ - int length = (use_fc ? 7 : 1) + (wr >= 1 ? wr - 1 : 0); + int prefix8_len = strlen(prefix8); + int length = (use_fc ? 7 : prefix8_len) + (wr >= 1 ? wr - 1 : 0); for(int i = 0; i < wr; i++) { length += utf8_len(comps[i]); } @@ -241,11 +246,16 @@ static void *path_normalize(char const *path, bool use_fc) uint16_t *fc = malloc((length + 1) * sizeof *fc); uint16_t *fc_init = fc; +#if GINT_OS_CP + memcpy(fc, u"\\fls0\\", 6*2); + fc += 6; +#else memcpy(fc, u"\\\\fls0\\", 7*2); fc += 7; +#endif for(int i = 0; i < wr; i++) { - if(i > 0) *fc++ = '\\'; + if(i > 0) *fc++ = dirsep; utf8_to_fc(fc, comps[i], (size_t)-1); fc += utf8_len(comps[i]); } @@ -258,10 +268,11 @@ static void *path_normalize(char const *path, bool use_fc) else { char *utf8 = malloc(length + 1); char *utf8_init = utf8; - *utf8++ = '/'; + memcpy(utf8, prefix8, prefix8_len); + utf8 += prefix8_len; for(int i = 0; i < wr; i++) { - if(i > 0) *utf8++ = '/'; + if(i > 0) *utf8++ = dirsep; strcpy(utf8, comps[i]); utf8 += utf8_len(comps[i]); } @@ -273,12 +284,17 @@ static void *path_normalize(char const *path, bool use_fc) } } + char *fs_path_normalize(char const *path) { - return path_normalize(path, false); + return path_normalize(path, false, NULL, '/'); } +char *fs_path_normalize_opt(char const *path, char const *prefix, int dirsep) +{ + return path_normalize(path, false, prefix, dirsep); +} uint16_t *fs_path_normalize_fc(char const *path) { - return path_normalize(path, true); + return path_normalize(path, true, NULL, '\\'); } diff --git a/src/fs/fugue/util.h b/src/fs/fugue/util.h index 0f66441..291d721 100644 --- a/src/fs/fugue/util.h +++ b/src/fs/fugue/util.h @@ -44,6 +44,9 @@ uint16_t *utf8_to_fc_alloc(uint16_t *prefix, char const *utf8, /* Same as fc_to_utf8() but allocates a string with malloc(). */ char *fc_to_utf8_alloc(uint16_t const *fc); +/* Same as fs_path_normalize() but with a prefix. If NULL, "/". */ +char *fs_path_normalize_opt(char const *path, char const *prefix, int dirsep); + #ifdef __cplusplus } #endif diff --git a/src/kernel/hardware.c b/src/kernel/hardware.c index 68d3d08..31b8635 100644 --- a/src/kernel/hardware.c +++ b/src/kernel/hardware.c @@ -176,8 +176,7 @@ void hw_detect(void) gint[HWCPUVR] = PVR; gint[HWCPUPR] = PRR; gint[HWCALC] = HWCALC_FXCP400; - // TODO: What filesystem implementation on the fx-CP 400? - gint[HWFS] = HWFS_NONE; + gint[HWFS] = HWFS_FUGUE; gint[HWRAM] = 16 << 20; // TOOD: How much ROM on the fx-CP 400? gint[HWROM] = 0; diff --git a/src/kernel/syscalls.S b/src/kernel/syscalls.S index fa71e9c..9f22036 100644 --- a/src/kernel/syscalls.S +++ b/src/kernel/syscalls.S @@ -33,6 +33,8 @@ .global _BFile_FindFirst .global _BFile_FindNext .global _BFile_FindClose +.global _BFile_FStat // fx-CP +.global _BFile_Mkdir // fx-CP /* Return to menu */ .global ___Timer_Install @@ -289,4 +291,35 @@ ___VRAMRestore: ___Reset: fixed(0xa0000000) +_BFile_Remove: + fixed(0x80057fc8) // atomic + HH2 (= 0x8005794e) +_BFile_Rename: + fixed(0x80057a06) +_BFile_Open: + fixed(0x80057854) +_BFile_Close: + fixed(0x80057912) +_BFile_Seek: + fixed(0x80057a96) +_BFile_Read: + fixed(0x800578a2) +_BFile_Write: + fixed(0x800578da) +_BFile_FindFirst: + fixed(0x8005a2ac) +_BFile_FindNext: + fixed(0x8005a5f0) +_BFile_FindClose: + fixed(0x8005a8ba) +_BFile_FStat: + fixed(0x8005798e) +_BFile_Mkdir: + fixed(0x80057814) +/* +_BFile_GetAddr: + fixed(0x80057c6a) +_BFile_Stat: + fixed(0x800579c2) +*/ + #endif /* GINT_OS_CP */