76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
//---
|
|
// fxBoot:fs:smemfs:read - Casio SMEM read primtive
|
|
//---
|
|
#include "fxBoot/fs/smemfs.h"
|
|
#include <gint/std/string.h>
|
|
#include <gint/bfile.h>
|
|
#include <gint/gint.h>
|
|
|
|
/* external symbols */
|
|
extern uint32_t (*cpu_setVBR)(uint32_t vbr, void (*conf_intc)(int), int arg);
|
|
|
|
/* world information */
|
|
extern void *kernel_env_casio;
|
|
extern void *kernel_env_gint;
|
|
extern void *gint_switch_to_world(void *buffctx);
|
|
|
|
|
|
/* generate_abolute_path(): Generate abolute path
|
|
|
|
This function will generate the absolute path of a file because Casio's open
|
|
primitive doesn't handle cannonical path */
|
|
static void generate_absolute_path(uint16_t *pathname,
|
|
struct smemfs_inode *inode, int *pos)
|
|
{
|
|
/* Check root inode */
|
|
if (inode == NULL) {
|
|
memcpy(pathname, u"\\\\fls0", 12);
|
|
*pos = 6;
|
|
return;
|
|
}
|
|
|
|
/* Get the parent inode name */
|
|
generate_absolute_path(pathname, inode->parent, pos);
|
|
|
|
/* Insert the file name */
|
|
pathname[(*pos)++] = '\\';
|
|
for (int i = 0; inode->name[i] != '\0'; ) {
|
|
pathname[*pos] = inode->name[i];
|
|
*pos = *pos + 1;
|
|
i = i + 1;
|
|
}
|
|
pathname[*pos] = '\0';
|
|
}
|
|
|
|
/* smemfs_read(): Read primitive */
|
|
ssize_t smemfs_pread(struct smemfs_inode *inode,
|
|
void *buf, size_t count, off_t pos)
|
|
{
|
|
uint16_t pathname[64];
|
|
ssize_t read;
|
|
int handle;
|
|
|
|
if (inode == NULL)
|
|
return (-1);
|
|
|
|
/* Generate the absolute pathname with FONTCHARACTER format */
|
|
generate_absolute_path(pathname, inode, &handle);
|
|
|
|
/* Switch from gint to the OS after a short wait */
|
|
gint_switch_to_world(kernel_env_casio);
|
|
|
|
/* Open, read and close the file using Casio's OS syscall */
|
|
read = -1;
|
|
handle = BFile_Open(pathname, BFile_ReadOnly);
|
|
if (handle >= 0) {
|
|
read = BFile_Read(handle, buf, count, pos);
|
|
BFile_Close(handle);
|
|
}
|
|
|
|
/* Then switch back to gint once the OS finishes working */
|
|
gint_switch_to_world(kernel_env_gint);
|
|
|
|
/* return the number of byte readed */
|
|
return (read);
|
|
}
|