fs: fx-CP 400 fixes, still unreliable when writing as previously known

This commit is contained in:
Lephe 2025-04-06 15:49:43 +02:00
parent 7180b52fd4
commit 8e64a8a107
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
7 changed files with 103 additions and 32 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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, '\\');
}

View file

@ -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

View file

@ -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;

View file

@ -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 */