Fix file_init as well as some bugs.

After this change, file_init will correctly wrap around in memory
like the other operations.

This commit also fixes a few issues I observed:

 - Hexadecimal numbers were garbled
 - Directories lacked a trailing slash
 - The size calculation was too pessimistic
This commit is contained in:
~d6 2024-09-20 20:24:22 -04:00
parent 1998e6cccc
commit 0f3b59d481
1 changed files with 23 additions and 19 deletions

View File

@ -90,6 +90,7 @@ stat_size(Uint16 addr, Uint16 len, off_t size)
Uint16 i;
for (i = 1; i <= len; i++) {
char c = '0' + (Uint8)(size & 0xf);
if (c > '9') c += 39;
uxn.ram[(addr + len - i) & 0xffff] = c;
size = size >> 4;
}
@ -106,9 +107,9 @@ stat_entry(Uint16 addr, char sym, off_t size, const char *s)
uxn.ram[(pos++) & 0xffff] = ' ';
while(*s)
uxn.ram[(pos++) & 0xffff] = *(s++);
if (sym == '-')
uxn.ram[(pos++) & 0xffff] = '/';
uxn.ram[(pos++) & 0xffff] = '\n';
/* like printf and friends, we don't count the trailing null */
uxn.ram[pos & 0xffff] = '\0';
return pos - addr;
}
@ -116,14 +117,21 @@ static Uint16
get_entry(Uint16 addr, Uint16 len, const char *pathname, const char *basename)
{
struct stat st;
if(len < strlen(basename) + 8) return 0;
int row_size = strlen(basename) + 6; /* 4 bytes, ' ', basename, '\n' */
char sym = 0;
off_t size = 0;
if(stat(pathname, &st)) sym = '!';
else if(S_ISDIR(st.st_mode)) sym = '-';
else if(st.st_size >= 0x10000) sym = '?';
else size = st.st_size;
return stat_entry(addr, sym, size, basename);
if(stat(pathname, &st))
sym = '!';
else if(S_ISDIR(st.st_mode)) {
sym = '-';
row_size++; /* directories have a '/' suffix */
} else if(st.st_size >= 0x10000)
sym = '?';
else
size = st.st_size;
return len < row_size ? 0 : stat_entry(addr, sym, size, basename);
}
static Uint16
@ -211,21 +219,17 @@ file_check_sandbox(UxnFile *c)
}
static Uint16
file_init(UxnFile *c, char *filename, size_t max_len, int override_sandbox)
file_init(UxnFile *c, Uint16 addr)
{
char *p = c->current_filename;
size_t len = sizeof(c->current_filename);
Uint16 i = addr;
reset(c);
if(len > max_len) len = max_len;
while(len) {
if((*p++ = *filename++) == '\0') {
if(!override_sandbox) /* override sandbox for loading roms */
for(;; p++, i++) {
if((*p = uxn.ram[i & 0xffff]) == '\0') {
file_check_sandbox(c);
return 0;
}
len--;
}
c->current_filename[0] = '\0';
return 0;
}
@ -369,7 +373,7 @@ file_deo(Uint8 port)
break;
case 0xa9:
addr = PEEK2(&uxn.dev[0xa8]);
res = file_init(&uxn_file[0], (char *)&uxn.ram[addr], 0x10000 - addr, 0);
res = file_init(&uxn_file[0], addr);
POKE2(&uxn.dev[0xa2], res);
break;
case 0xad:
@ -403,7 +407,7 @@ file_deo(Uint8 port)
break;
case 0xb9:
addr = PEEK2(&uxn.dev[0xb8]);
res = file_init(&uxn_file[1], (char *)&uxn.ram[addr], 0x10000 - addr, 0);
res = file_init(&uxn_file[1], addr);
POKE2(&uxn.dev[0xb2], res);
break;
case 0xbd: