fsctl - v0.0.0-1 : project architecture + fugue root dirent handling (WIP)
*common* | add build system | add neovim ALE configuration | first Fugue File System abstraction (maxi WIP) | first menus (ROM, FS info, FAT viewer, ...) (WIP)
This commit is contained in:
commit
b089b00882
|
@ -0,0 +1,17 @@
|
|||
# Build files
|
||||
/build-fx
|
||||
/build-cg
|
||||
/build-cg-push
|
||||
/*.g1a
|
||||
/*.g3a
|
||||
|
||||
# Python bytecode
|
||||
__pycache__/
|
||||
|
||||
# Common IDE files
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
.vscode
|
||||
|
||||
# custom
|
||||
commit.txt
|
|
@ -0,0 +1,58 @@
|
|||
" Force-display trailing whitespaces
|
||||
highlight ExtraWhitespace ctermbg=red guibg=red
|
||||
match ExtraWhitespace /\s\+$/
|
||||
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
|
||||
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
|
||||
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
|
||||
autocmd BufWinLeave * call clearmatches()
|
||||
|
||||
" indicate the compiler to use
|
||||
let g:ale_asm_gcc_executable = 'sh-elf-vhex-gcc'
|
||||
let g:ale_c_gcc_executable = 'sh-elf-vhex-gcc'
|
||||
let g:ale_c_cc_executable = 'sh-elf-vhex-gcc'
|
||||
let g:ale_cpp_gcc_executable = 'sh-elf-vhex-gcc'
|
||||
|
||||
" Find GiteaPC include directory information
|
||||
let s:_hdrflags = [
|
||||
\ '-I./include/',
|
||||
\ '-I'.$HOME.'/.local/share/giteapc/Lephenixnoir/gint/include/',
|
||||
\ ]
|
||||
let s:_cflags = [
|
||||
\ '-DFXCG50',
|
||||
\ '-std=c11',
|
||||
\ '-Wall',
|
||||
\ '-Wextra',
|
||||
\ ]
|
||||
let s:_asmflags = [
|
||||
\ '-DFXCG50',
|
||||
\ '-x assembler-with-cpp',
|
||||
\ '-Wall',
|
||||
\ '-Wextra',
|
||||
\ '-m4-nofpu',
|
||||
\ '-mb',
|
||||
\ '-Wa,--dsp',
|
||||
\ ]
|
||||
|
||||
" convert table into string
|
||||
let s:_hdrflags = join(s:_hdrflags)
|
||||
let s:_asmflags = join(s:_asmflags)
|
||||
let s:_cflags = join(s:_cflags)
|
||||
|
||||
" Patch option
|
||||
" @note
|
||||
" - we setup cpp because header file is considered ad C++ file
|
||||
" - we force sh-elf-vhex for assembly file only
|
||||
let g:ale_asm_gcc_options = s:_asmflags
|
||||
let g:ale_c_gcc_options = s:_cflags.' '.s:_hdrflags
|
||||
let g:ale_c_cc_options = s:_cflags.' '.s:_hdrflags
|
||||
let g:ale_cpp_cc_options = s:_cflags.' '.s:_hdrflags
|
||||
let g:ale_cpp_gcc_options = s:_cflags.' '.s:_hdrflags
|
||||
|
||||
" Enable completion
|
||||
let g:ale_completion_enabled = 1
|
||||
|
||||
" Enable linter when enter is pressed
|
||||
let g:ale_lint_on_enter = 1
|
||||
|
||||
" Force display non-printable chars
|
||||
set list
|
|
@ -0,0 +1,41 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(fsctl)
|
||||
|
||||
include(GenerateG3A)
|
||||
find_package(Gint 2.9 REQUIRED)
|
||||
|
||||
set(SOURCES
|
||||
src/main.c
|
||||
|
||||
# fugue
|
||||
src/fugue/mount.c
|
||||
src/fugue/dir.c
|
||||
src/fugue/core/cluster.c
|
||||
src/fugue/core/sector.c
|
||||
src/fugue/core/fat.c
|
||||
|
||||
# menu
|
||||
src/menu/rom.c
|
||||
src/menu/info.c
|
||||
src/menu/fat.c
|
||||
src/menu/list.c
|
||||
|
||||
#utils
|
||||
src/utils/fs_table.c
|
||||
)
|
||||
|
||||
add_executable(fsctl ${SOURCES})
|
||||
target_compile_options(fsctl PRIVATE -Wall -Wextra -Os)
|
||||
target_link_libraries(fsctl Gint::Gint)
|
||||
target_include_directories(fsctl PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
||||
message(FATAL_ERROR "not supported device for now")
|
||||
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
||||
generate_g3a(
|
||||
TARGET fsctl
|
||||
OUTPUT "fsctl.g3a"
|
||||
NAME "fsctl"
|
||||
ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png
|
||||
)
|
||||
endif()
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,24 @@
|
|||
#ifndef FSCTL_FUGUE_H
|
||||
#define FSCTL_FUGUE_H 1
|
||||
|
||||
#include "fsctl/fugue/bits/fs.h"
|
||||
#include "fsctl/fugue/bits/dir.h"
|
||||
#include "fsctl/fugue/bits/file.h"
|
||||
|
||||
//---
|
||||
// API
|
||||
//---
|
||||
|
||||
/* fugue_fs_mount() : try to initialize the FS */
|
||||
extern int fugue_fs_mount(fugue_fs_t *fsinfo, void *addr);
|
||||
|
||||
/* fugue_fs_opendir() : opendir-like function */
|
||||
extern int fugue_fs_opendir(fugue_dir_t *dir);
|
||||
|
||||
/* fugue_fs_readdir() : readdir-like function */
|
||||
extern int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file);
|
||||
|
||||
/* fugue_fs_closedir() : closedir-like function */
|
||||
extern int fugue_fs_closedir(fugue_dir_t *dir);
|
||||
|
||||
#endif /* FSCTL_FUGUE_H */
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef FSCTL_FUGUE_BITS_DIR_H
|
||||
#define FSCTL_FUGUE_BITS_DIR_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fsctl/fugue/bits/fs.h"
|
||||
|
||||
/* fugue_dir : Fugue directory abstraction */
|
||||
struct fugue_dir
|
||||
{
|
||||
/* middle-level information */
|
||||
uintptr_t current_dir_addr;
|
||||
uintptr_t cluster_addr_start;
|
||||
uintptr_t cluster_addr_end;
|
||||
uint32_t cluster_idx;
|
||||
|
||||
/* low-level information */
|
||||
struct {
|
||||
fugue_fs_t fs;
|
||||
} _private;
|
||||
|
||||
};
|
||||
typedef struct fugue_dir fugue_dir_t;
|
||||
|
||||
#endif /* FSCTL_FUGUE_BITS_DIR_H */
|
|
@ -0,0 +1,94 @@
|
|||
#ifndef FSCTL_FUGUE_BITS_FAT_H
|
||||
#define FSCTL_FUGUE_BITS_FAT_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* struct fugue_fat_vbr : Volume Boot Record (hardcoded for Fugue) */
|
||||
struct fugue_fat_vbr
|
||||
{
|
||||
// common boot structure
|
||||
uint8_t BS_jmpBoot[3];
|
||||
uint8_t BS_OEMName[8];
|
||||
|
||||
// BIOS parameter Block
|
||||
uint16_t BPB_BytsPerSec;
|
||||
uint8_t BPB_SecPerClus;
|
||||
uint16_t BPB_RsvdSecCnt;
|
||||
uint8_t BPB_NumFATs;
|
||||
uint16_t BPB_RootEntCnt;
|
||||
uint16_t BPB_TotSec16;
|
||||
uint8_t BPB_Media;
|
||||
uint16_t BPB_FATSz16;
|
||||
uint16_t BPB_SecPerTrk;
|
||||
uint16_t BPB_NumHeads;
|
||||
uint32_t BPB_HiddSec;
|
||||
uint32_t BPB_TotSec32;
|
||||
|
||||
// Extended BIOS Parameter Block
|
||||
uint8_t BS_DrvNum;
|
||||
uint8_t BS_Reserved1;
|
||||
uint8_t BS_BootSig;
|
||||
uint8_t BS_VolID[4];
|
||||
uint8_t BS_VolLab[11];
|
||||
uint8_t BS_FilSysType[8];
|
||||
uint8_t _unused[448];
|
||||
|
||||
// Signature
|
||||
uint8_t Signature_word[2];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* FUGUE_DIR_ATTR_* : Attribute information */
|
||||
#define FUGUE_DIR_ATTR_RDONLY 0x01
|
||||
#define FUGUE_DIR_ATTR_HIDDEN 0x02
|
||||
#define FUGUE_DIR_ATTR_SYSTEM 0x04
|
||||
#define FUGUE_DIR_ATTR_VOLUME 0x08
|
||||
#define FUGUE_DIR_ATTR_DIR 0x10
|
||||
#define FUGUE_DIR_ATTR_ARCHIVE 0x20
|
||||
#define FUGUE_DIR_ATTR_DEVICE 0x40
|
||||
#define FUGUE_DIR_ATTR_LFN 0x0f
|
||||
|
||||
/* fugue_fat_dir : directory strcuture information */
|
||||
struct fugue_fat_dir
|
||||
{
|
||||
uint8_t DIR_Name[8];
|
||||
uint8_t DIR_Exts[3];
|
||||
uint8_t DIR_Attr;
|
||||
uint8_t _unknown0[1+1+2+2+2];
|
||||
uint16_t DIR_FstClusHI;
|
||||
uint8_t _unknown1[2+2];
|
||||
uint16_t DIR_FstClusLO;
|
||||
uint32_t DIR_FileSize;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* fugue_fat_dir_name : Fugue directory name strcuture */
|
||||
struct fugue_fat_dir_name
|
||||
{
|
||||
struct {
|
||||
uint8_t :2;
|
||||
uint8_t last :1;
|
||||
uint8_t :1;
|
||||
uint8_t id :4;
|
||||
} DIR_Secquence;
|
||||
uint16_t DIR_Char0;
|
||||
uint16_t DIR_Char1;
|
||||
uint16_t DIR_Char2;
|
||||
uint16_t DIR_Char3;
|
||||
uint16_t DIR_Char4;
|
||||
uint8_t DIR_Attr; // must be 0x0f
|
||||
uint8_t DIR_Type; // must be 0x00
|
||||
uint8_t checksum;
|
||||
uint16_t DIR_Char5;
|
||||
uint16_t DIR_Char6;
|
||||
uint16_t DIR_Char7;
|
||||
uint16_t DIR_Char8;
|
||||
uint16_t DIR_Char9;
|
||||
uint16_t DIR_Char10;
|
||||
uint16_t DIR_FstClus; // must be 0x0000
|
||||
uint16_t DIR_Char11;
|
||||
uint16_t DIR_Char12;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
#endif /* FSCTL_FUGUE_BITS_FAT_H */
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef FSCTL_FUGUE_BITS_FILE_H
|
||||
#define FSCTL_FUGUE_BITS_FILE_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* FUGUE_FILE_TYPE_* : supported file types */
|
||||
#define FUGUE_FILE_TYPE_DIR 0x01
|
||||
#define FUGUE_FILE_TYPE_FILE 0x02
|
||||
|
||||
/* struct fugue_file : Fugue file abstraction */
|
||||
struct fugue_file
|
||||
{
|
||||
char name[210];
|
||||
int type;
|
||||
uint32_t size;
|
||||
};
|
||||
typedef struct fugue_file fugue_file_t;
|
||||
|
||||
#endif /* FSCTL_FUGUE_BITS_FILE_H */
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef FSCTL_FUGUE_BITS_FS_H
|
||||
#define FSCTL_FUGUE_BITS_FS_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* fugue_fs : Fugue File System abstraction */
|
||||
struct fugue_fs
|
||||
{
|
||||
/* fs properties */
|
||||
struct {
|
||||
char const *type;
|
||||
size_t capacity;
|
||||
size_t free;
|
||||
size_t used;
|
||||
int cluster_nb;
|
||||
int cluster_resv;
|
||||
int cluster_free;
|
||||
int cluster_dead;
|
||||
int cluster_used;
|
||||
int cluster_error;
|
||||
size_t cluster_size;
|
||||
int cluster_nb_sector;
|
||||
int sector_size;
|
||||
int sector_data_nb;
|
||||
int sector_root_nb;
|
||||
size_t fats_size;
|
||||
size_t fat0_size;
|
||||
size_t fat1_size;
|
||||
int fat_sec;
|
||||
} props;
|
||||
|
||||
/* debug-level information */
|
||||
struct {
|
||||
int a; //TODO
|
||||
} _logs;
|
||||
|
||||
/* memory related and low-level information */
|
||||
struct {
|
||||
struct fugue_fat_vbr *vbr;
|
||||
void *fat0;
|
||||
void *fat1;
|
||||
void *root;
|
||||
} _private;
|
||||
};
|
||||
typedef struct fugue_fs fugue_fs_t;
|
||||
|
||||
#endif /* FSCTL_FUGUE_BITS_FS_H */
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef FSCTL_FUGUE_CLUSTER_H
|
||||
#define FSCTL_FUGUE_CLUSTER_H 1
|
||||
|
||||
#include "fsctl/fugue/bits/fs.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_cluster_is_valid() : check cluster validity */
|
||||
extern int fugue_cluster_is_valid(fugue_fs_t *fs, int cluster_idx);
|
||||
|
||||
/* fugue_cluster_find_next() : find the next cluster address if available */
|
||||
extern uintptr_t fugue_cluster_find_next(fugue_fs_t *fs, uint32_t cluster_idx);
|
||||
|
||||
#endif /* FSCTL_FUGUE_CLUSTER_H */
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef FSCTL_FUGUE_DIRENT_H
|
||||
#define FSCTL_FUGUE_DIRENT_H 1
|
||||
|
||||
#include "fsctl/fugue/bits/dir.h"
|
||||
#include "fsctl/fugue/bits/file.h"
|
||||
|
||||
//---
|
||||
// API
|
||||
//---
|
||||
|
||||
/* fugue_dirent_dir_fetch() : fetch the current dir blob and walk to next */
|
||||
extern void *fugue_dirent_dir_fetch(fugue_dir_t *dirent);
|
||||
|
||||
/* fugue_dirent_name_fetch() : fetch fragment */
|
||||
extern int fugue_dirent_name_fetch(
|
||||
fugue_dir_t *dirent,
|
||||
fugue_file_t *file,
|
||||
void *dir
|
||||
);
|
||||
|
||||
#endif /* FSCTL_FUGUE_DIRENT_H */
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef FSCTL_FUGUE_FAT_H
|
||||
#define FSCTL_FUGUE_FAT_H 1
|
||||
|
||||
#include "fsctl/fugue/bits/fs.h"
|
||||
|
||||
//---
|
||||
// API
|
||||
//---
|
||||
|
||||
/* fugue_fat_is_vaild() : Check the complet FATs validity */
|
||||
extern int fugue_fat_is_vaild(fugue_fs_t *fs);
|
||||
|
||||
#endif /* FSCTL_FUGUE_FAT_H */
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef FSCTL_FUGUE_SECTOR_H
|
||||
#define FSCTL_FUGUE_SECTOR_H 1
|
||||
|
||||
#include "fsctl/fugue/bits/fat.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_sector_is_vbr() : check if the given address is a potential VBR */
|
||||
extern int fugue_sector_is_vbr(struct fugue_fat_vbr *vbr);
|
||||
|
||||
/* fugue_sector_is_invalid() : check if the sector is invalide */
|
||||
extern int fugue_sector_is_invalid(void *sector);
|
||||
|
||||
#endif /* FSCTL_FUGUE_SECTOR_H */
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef FSCTL_FUGUE_UTILS_H
|
||||
#define FSCTL_FUGUE_UTILS_H 1
|
||||
|
||||
/* FAT_TO_WORD() : helper for 16bit value */
|
||||
#define FAT_WORD(x) \
|
||||
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
|
||||
|
||||
/* FAT_LONG() : helper for 32bit value */
|
||||
#define FAT_LONG(x) ( \
|
||||
((x & 0xff000000) >> 24) \
|
||||
| ((x & 0x00ff0000) >> 8) \
|
||||
| ((x & 0x0000ff00) << 8) \
|
||||
| ((x & 0x000000ff) << 24) \
|
||||
)
|
||||
|
||||
#endif /* FSCTL_FUGUE_UTILS_H */
|
|
@ -0,0 +1,4 @@
|
|||
#include "fsctl/menu/fat.h"
|
||||
#include "fsctl/menu/rom.h"
|
||||
#include "fsctl/menu/info.h"
|
||||
#include "fsctl/menu/list.h"
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef FSCTL_MENU_FAT_H
|
||||
#define FSCTL_MENU_FAT_H 1
|
||||
|
||||
/* fat_menu_init() : init menu */
|
||||
extern void fat_menu_init(void);
|
||||
|
||||
/* fat_menu_display() : display menu */
|
||||
extern void fat_menu_display(void);
|
||||
|
||||
/* fat_menu_keyboard() : handle keyboard */
|
||||
extern void fat_menu_keyboard(int key);
|
||||
|
||||
#endif /* FSCTL_MENU_FAT_H */
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef FSCTL_MENU_INFO_H
|
||||
#define FSCTL_MENU_INFO_H 1
|
||||
|
||||
/* info_menu_init() : init menu */
|
||||
extern void info_menu_init(void);
|
||||
|
||||
/* info_menu_display() : display menu */
|
||||
extern void info_menu_display(void);
|
||||
|
||||
/* info_menu_keyboard() : handle keyboard */
|
||||
extern void info_menu_keyboard(int key);
|
||||
|
||||
#endif /* FSCTL_MENU_INFO_H */
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef FSCTL_MENU_LIST_H
|
||||
#define FSCTL_MENU_LIST_H 1
|
||||
|
||||
/* list_menu_init() : init menu */
|
||||
extern void list_menu_init(void);
|
||||
|
||||
/* list_menu_display() : display menu */
|
||||
extern void list_menu_display(void);
|
||||
|
||||
/* list_menu_keyboard() : handle keyboard */
|
||||
extern void list_menu_keyboard(int key);
|
||||
|
||||
#endif /* FSCTL_MENU_LIST_H */
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef FSCTL_MENU_ROM_H
|
||||
#define FSCTL_MENU_ROM_H 1
|
||||
|
||||
/* rom_menu_init() : init menu */
|
||||
extern void rom_menu_init(void);
|
||||
|
||||
/* rom_menu_display() : display menu */
|
||||
extern void rom_menu_display(void);
|
||||
|
||||
/* rom_menu_keyboard() : handle keyboard */
|
||||
extern void rom_menu_keyboard(int key);
|
||||
|
||||
#endif /* FSCTL_MENU_ROM_H */
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef FSCTL_MENU_UTILS_H
|
||||
#define FSCTL_MENU_UTILS_H 1
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
//---
|
||||
// Helpers
|
||||
//---
|
||||
|
||||
#define _printXY(x, y, ...) \
|
||||
dprint((x * 10) + 3, (y * 12) + 5, C_BLACK, __VA_ARGS__)
|
||||
|
||||
#define _rectXY(x, y, color) \
|
||||
drect_border( \
|
||||
(x * 12) + 3 + 85, \
|
||||
(y * 12) + 3, \
|
||||
(x * 12) + 3 + 85 + 12, \
|
||||
(y * 12) + 3 + 12, \
|
||||
color, \
|
||||
1, \
|
||||
C_BLACK \
|
||||
)
|
||||
|
||||
#define _lrectXY(x, y, color) \
|
||||
drect_border( \
|
||||
(x * 48) + 3 + 85, \
|
||||
(y * 12) + 3, \
|
||||
(x * 48) + 3 + 85 + 48, \
|
||||
(y * 12) + 3 + 12, \
|
||||
color, \
|
||||
1, \
|
||||
C_BLACK \
|
||||
)
|
||||
#define _lrectTextXY(x, y, hex) \
|
||||
dprint_opt( \
|
||||
(x * 48) + 3 + 85 + 24, \
|
||||
(y * 12) + 3 + 6, \
|
||||
C_BLACK, \
|
||||
C_NONE, \
|
||||
DTEXT_CENTER, \
|
||||
DTEXT_MIDDLE, \
|
||||
"%04X", \
|
||||
hex \
|
||||
)
|
||||
|
||||
#endif /* FUGUE_MENU_ROM_H */
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef FSCTL_UTILS_FS_TABLE_H
|
||||
#define FSCTL_UTILS_FS_TABLE_H 1
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "fsctl/fugue/bits/fs.h"
|
||||
|
||||
//---
|
||||
// Types
|
||||
//---
|
||||
|
||||
/* struct fs_table : FS table entry information */
|
||||
struct fs_table
|
||||
{
|
||||
bool is_valid;
|
||||
uintptr_t vbr;
|
||||
fugue_fs_t fs;
|
||||
};
|
||||
typedef struct fs_table fs_table_t;
|
||||
|
||||
//---
|
||||
// API
|
||||
//---
|
||||
|
||||
/* fs_table_init() : initialize FS table */
|
||||
extern void fs_table_init(void);
|
||||
|
||||
/* fs_table_update() : try to update internal fs table */
|
||||
extern int fs_table_update(fugue_fs_t *fs);
|
||||
|
||||
/* fs_table_info() : get fs table information */
|
||||
extern int fs_table_info(fugue_fs_t *fs, int *fs_idx, int *nb_fs);
|
||||
|
||||
/* fs_table_dtitle() : display FS table title menu */
|
||||
extern void fs_table_dtitle(void);
|
||||
|
||||
/* fs_table_select() : select a FS if available */
|
||||
extern int fs_table_select(int idx);
|
||||
|
||||
/* fs_table_select_left() : try to change to the idx - 1 */
|
||||
extern int fs_table_select_left(void);
|
||||
|
||||
/* fs_table_select_right() : try to change to the idx + 1 */
|
||||
extern int fs_table_select_right(void);
|
||||
|
||||
#endif /* FSCTL_UTILS_FS_TABLE_H */
|
|
@ -0,0 +1,43 @@
|
|||
#include "fsctl/fugue/cluster.h"
|
||||
#include "fsctl/fugue/sector.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_cluster_is_valid() : check cluster validity */
|
||||
//TODO : support FAT12 / FAT32
|
||||
int fugue_cluster_is_valid(fugue_fs_t *fs, int cluster_idx)
|
||||
{
|
||||
void *sector;
|
||||
uint16_t id;
|
||||
|
||||
id = FAT_WORD(((uint16_t *)fs->_private.fat0)[cluster_idx]);
|
||||
if (id == 0x0000)
|
||||
return 0;
|
||||
if (cluster_idx == 0)
|
||||
return 0;
|
||||
|
||||
/* special check for the root fake cluster */
|
||||
if (cluster_idx == 1)
|
||||
{
|
||||
if (id != 0xffff)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cluster_idx -= 2;
|
||||
sector = (void*)((uintptr_t)(fs->props.cluster_nb_sector * cluster_idx));
|
||||
sector = (void*)((uintptr_t)sector + fs->props.sector_root_nb);
|
||||
sector = (void*)((uintptr_t)sector * 512);
|
||||
sector = (void*)((uintptr_t)sector + (uintptr_t)fs->_private.root);
|
||||
|
||||
for (int i = 0 ; i < fs->props.cluster_nb_sector ; i++)
|
||||
{
|
||||
if (fugue_sector_is_invalid(sector))
|
||||
return -2;
|
||||
sector = (void *)((uintptr_t)sector + 512);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#include "fsctl/fugue/dirent.h"
|
||||
#include "fsctl/fugue/cluster.h"
|
||||
#include "fsctl/fugue/bits/fat.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _fugue_dirent_checksum() : Fugue checksum handling */
|
||||
static uint8_t _fugue_dirent_checksum(uintptr_t directory)
|
||||
{
|
||||
uint8_t *block;
|
||||
uint8_t checksum;
|
||||
int a;
|
||||
int b;
|
||||
|
||||
checksum = 0;
|
||||
block = (void *)directory;
|
||||
for (int i = 0 ; i < 11 ; ++i)
|
||||
{
|
||||
checksum = checksum & 0xff;
|
||||
a = checksum / 2;
|
||||
b = checksum * 128;
|
||||
checksum = a | b;
|
||||
checksum = checksum + block[i];
|
||||
}
|
||||
checksum = checksum & 0xff;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_dirent_dir_fetch() : fetch the current dir blob and walk to next */
|
||||
void *fugue_dirent_dir_fetch(fugue_dir_t *dirent)
|
||||
{
|
||||
void *dir;
|
||||
|
||||
dir = (void*)dirent->current_dir_addr;
|
||||
if (dir == NULL)
|
||||
return NULL;
|
||||
|
||||
dirent->current_dir_addr += 32;
|
||||
if (dirent->current_dir_addr < dirent->cluster_addr_end)
|
||||
return dir;
|
||||
|
||||
dirent->cluster_addr_start = fugue_cluster_find_next(
|
||||
&dirent->_private.fs,
|
||||
dirent->cluster_idx
|
||||
);
|
||||
dirent->cluster_addr_end = dirent->cluster_addr_start;
|
||||
if (dirent->cluster_addr_start != 0x00000000)
|
||||
dirent->cluster_addr_end += dirent->_private.fs.props.cluster_size;
|
||||
return dir;
|
||||
}
|
||||
|
||||
/* fugue_dirent_name_fetch() : fetch fragment */
|
||||
int fugue_dirent_name_fetch(fugue_dir_t *dirent, fugue_file_t *file, void *dir)
|
||||
{
|
||||
struct fugue_fat_dir_name *lfn;
|
||||
|
||||
lfn = (void *)dir;
|
||||
|
||||
//---
|
||||
// check directory block validity
|
||||
//---
|
||||
|
||||
if (lfn->DIR_Attr != FUGUE_DIR_ATTR_LFN)
|
||||
return -1;
|
||||
if (lfn->DIR_Type != 0x00)
|
||||
return -2;
|
||||
if (lfn->DIR_FstClus != 0x0000)
|
||||
return -3;
|
||||
//TODO : check Secquence validity
|
||||
if (lfn->checksum != _fugue_dirent_checksum(dirent->current_dir_addr))
|
||||
return -5;
|
||||
|
||||
//---
|
||||
// Dump name fragment
|
||||
//---
|
||||
|
||||
//TODO: dump
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
#include "fsctl/fugue/fat.h"
|
||||
#include "fsctl/fugue/sector.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_fat_is_vaild() : Check the complet FATs validity */
|
||||
int fugue_fat_is_vaild(fugue_fs_t *fs)
|
||||
{
|
||||
uint16_t *cluster_map;
|
||||
uint32_t *sector;
|
||||
uint16_t cluster;
|
||||
|
||||
/* check FATID and root value */
|
||||
sector = (void *)fs->_private.fat0;
|
||||
if (((uint8_t*)sector)[0] != 0xf8 || ((uint8_t*)sector)[1] != 0xff)
|
||||
return -1;
|
||||
if (((uint8_t*)sector)[2] != 0xff || ((uint8_t*)sector)[3] != 0xff)
|
||||
return -1;
|
||||
sector = (void *)fs->_private.fat1;
|
||||
if (((uint8_t*)sector)[0] != 0xf8 || ((uint8_t*)sector)[1] != 0xff)
|
||||
return -1;
|
||||
if (((uint8_t*)sector)[2] != 0xff || ((uint8_t*)sector)[3] != 0xff)
|
||||
return -1;
|
||||
|
||||
/* check complet valid FAT
|
||||
* @note
|
||||
* - full Fugue FAT area take 5120 bytes -> 10x512 -> 10 sectors
|
||||
* - also check the root reserved sectors */
|
||||
sector = (void*)fs->_private.fat0;
|
||||
for (int i = 0 ; i < 10 + fs->props.sector_root_nb ; i++)
|
||||
{
|
||||
if (fugue_sector_is_invalid(sector))
|
||||
return -1;
|
||||
sector = (void *)((uintptr_t)sector + 512);
|
||||
}
|
||||
|
||||
/* follows each cluster and check that all sector are used */
|
||||
cluster_map = (void *)fs->_private.fat1;
|
||||
fs->props.cluster_resv = 0;
|
||||
fs->props.cluster_free = 0;
|
||||
fs->props.cluster_used = 0;
|
||||
fs->props.cluster_dead = 0;
|
||||
fs->props.cluster_error = 0;
|
||||
for (int i = 1 ; i < 256 ; i++)
|
||||
{
|
||||
cluster = FAT_WORD(cluster_map[i]);
|
||||
if (cluster == 0x0000) {
|
||||
fs->props.cluster_free += 1;
|
||||
continue;
|
||||
}
|
||||
if (cluster == 0x0001) {
|
||||
fs->props.cluster_resv += 1;
|
||||
continue;
|
||||
}
|
||||
if (cluster == 0xfff7) {
|
||||
fs->props.cluster_dead += 1;
|
||||
continue;
|
||||
}
|
||||
if (cluster >= 0xfff8) {
|
||||
fs->props.cluster_used += 1;
|
||||
continue;
|
||||
}
|
||||
if (cluster < (fs->props.cluster_nb + 1)) {
|
||||
fs->props.cluster_used += 1;
|
||||
continue;
|
||||
}
|
||||
fs->props.cluster_error += 1;
|
||||
fs->props.test = cluster;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "fsctl/fugue/sector.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_sector_is_vbr() : check if the given address is a potential VBR */
|
||||
int fugue_sector_is_vbr(struct fugue_fat_vbr *vbr)
|
||||
{
|
||||
static const struct fugue_fat_vbr fugue_fat_vbr = {
|
||||
/* common boot information */
|
||||
.BS_jmpBoot = { 0xeb, 0x3c, 0x90 },
|
||||
.BS_OEMName = "MSDOS5.0",
|
||||
|
||||
/* BIOS Parameter Block */
|
||||
.BPB_BytsPerSec = 512,
|
||||
.BPB_SecPerClus = 8, // <--- not hardcoded by Casio
|
||||
.BPB_RsvdSecCnt = 0, // <--- not hardcoded by Casio
|
||||
.BPB_NumFATs = 2,
|
||||
.BPB_RootEntCnt = 0, // <--- not hardcoded by Casio
|
||||
.BPB_TotSec16 = 0, // <--- not hardcoded
|
||||
.BPB_Media = 0xf8,
|
||||
.BPB_FATSz16 = 0, // <--- not hardcoded
|
||||
.BPB_SecPerTrk = 0, // <--- not hardcoded
|
||||
.BPB_HiddSec = 0, // <--- not hardcoded
|
||||
.BPB_TotSec32 = 0, // <--- not hardcoded
|
||||
|
||||
/* Extended BIOS Parameter Block */
|
||||
.BS_DrvNum = 0x80,
|
||||
.BS_Reserved1 = 0,
|
||||
.BS_BootSig = 0x29,
|
||||
.BS_VolID = {0x00, 0x00, 0x00, 0x00},
|
||||
.BS_VolLab = "CASIO ",
|
||||
.BS_FilSysType = "FAT16 ",
|
||||
|
||||
/* signature */
|
||||
.Signature_word = {0x55, 0xaa}
|
||||
};
|
||||
|
||||
//---
|
||||
// VBR global hardcoded value check
|
||||
//---
|
||||
|
||||
/* check common boot information */
|
||||
if (memcmp(vbr, &fugue_fat_vbr, 11) != 0)
|
||||
return -1;
|
||||
|
||||
/* check BIOS Parameter Block */
|
||||
if (FAT_WORD(vbr->BPB_BytsPerSec) != fugue_fat_vbr.BPB_BytsPerSec)
|
||||
return -1;
|
||||
if (vbr->BPB_NumFATs != fugue_fat_vbr.BPB_NumFATs)
|
||||
return -1;
|
||||
if (vbr->BPB_Media != fugue_fat_vbr.BPB_Media)
|
||||
return -1;
|
||||
|
||||
/* check Extended BIOS Parameter Block */
|
||||
if (memcmp(&(vbr->BS_DrvNum), &(fugue_fat_vbr.BS_DrvNum), 474) != 0)
|
||||
return -1;
|
||||
|
||||
/* check signature */
|
||||
if (vbr->Signature_word[0] != fugue_fat_vbr.Signature_word[0])
|
||||
return -1;
|
||||
if (vbr->Signature_word[1] != fugue_fat_vbr.Signature_word[1])
|
||||
return -1;
|
||||
|
||||
//---
|
||||
// FAT validity check
|
||||
//---
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fugue_sector_is_invalid() : check if the sector is invalide */
|
||||
int fugue_sector_is_invalid(void *sector)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0 ; x < 512 / 2 ; x++)
|
||||
{
|
||||
if (((uint32_t *)sector)[x] != 0xffffffff)
|
||||
break;
|
||||
}
|
||||
if (x >= (512 / 4))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/fugue/bits/fat.h"
|
||||
#include "fsctl/fugue/dirent.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_fs_opendir() : opendir-like function */
|
||||
int fugue_fs_opendir(fugue_dir_t *dir)
|
||||
{
|
||||
fugue_fs_t fs;
|
||||
|
||||
if (dir == NULL)
|
||||
return -1;
|
||||
if (fs_table_info(&fs, NULL, NULL) != 0)
|
||||
return -2;
|
||||
memset(dir, 0x00, sizeof(fugue_dir_t));
|
||||
memcpy(&dir->_private.fs, &fs, sizeof(fugue_fs_t));
|
||||
dir->current_dir_addr = (uintptr_t)fs._private.root;
|
||||
dir->cluster_addr = (uintptr_t)fs._private.root;
|
||||
dir->cluster_size = fs.props.sector_root_nb * 512;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fugue_fs_readdir() : readdir-like function */
|
||||
int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file)
|
||||
{
|
||||
struct fugue_fat_dir *dir;
|
||||
fugue_dir_t dirent_backup;
|
||||
bool error;
|
||||
bool vfat;
|
||||
|
||||
if (dirent == NULL)
|
||||
return -1;
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
if (dirent->current_dir_addr == 0x00000000)
|
||||
return -2;
|
||||
|
||||
memset(file, 0x00, sizeof(fugue_file_t));
|
||||
memcpy(&dirent_backup, dirent, sizeof(fugue_dir_t));
|
||||
|
||||
vfat = false;
|
||||
error = false;
|
||||
while (error == false)
|
||||
{
|
||||
/* fetch the current FAT directory and walk */
|
||||
dir = fugue_dirent_dir_fetch(dirent);
|
||||
if (dir == NULL) {
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//---
|
||||
// handle special name behaviour
|
||||
//---
|
||||
|
||||
switch(dir->DIR_Name[0])
|
||||
{
|
||||
/* handle free directory */
|
||||
case 0x00:
|
||||
//fugue_logger_warn("opendir: wierd empty directory block ")
|
||||
error = true;
|
||||
continue;
|
||||
|
||||
/* dot and dotdot special file */
|
||||
case '.':
|
||||
if (memcmp(dir->DIR_Name, ". ", 2) == 0)
|
||||
memcpy(file->name, ".", 2);
|
||||
if (memcmp(dir->DIR_Name, ".. ", 3) == 0)
|
||||
memcpy(file->name, "..", 3);
|
||||
if (vfat == true)
|
||||
//fugue_logger_warn("opendir: wierd directory block ")
|
||||
file->type = FUGUE_FILE_TYPE_DIR;
|
||||
file->size = FAT_LONG(dir->DIR_FileSize);
|
||||
return 0;
|
||||
|
||||
/* removed entry */
|
||||
case 0x05:
|
||||
case 0xe5:
|
||||
//fugue_logger_notice("opendir : removed entry");
|
||||
memset(file, 0x00, sizeof(fugue_file_t));
|
||||
vfat = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
//---
|
||||
// handle directory attribute
|
||||
//---
|
||||
|
||||
switch(dir->DIR_Attr)
|
||||
{
|
||||
/* handle file name fragment */
|
||||
case FUGUE_DIR_ATTR_VNAME:
|
||||
fugue_dirent_name_fetch(dirent, file);
|
||||
vfat = true;
|
||||
break;
|
||||
|
||||
/* file handling */
|
||||
case FUGUE_DIR_ATTR_RDONLY:
|
||||
case FUGUE_DIR_ATTR_HIDDEN:
|
||||
case FUGUE_DIR_ATTR_SYSTEM:
|
||||
case FUGUE_DIR_ATTR_DIR:
|
||||
case FUGUE_DIR_ATTR_ARCHIVE:
|
||||
case FUGUE_DIR_ATTR_DEVICE:
|
||||
//TODO : file type
|
||||
file->type = FUGUE_FILE_TYPE_FILE;
|
||||
file->size = FAT_LONG(dir->DIR_FileSize);
|
||||
return 0;
|
||||
|
||||
/* other attribute not handled */
|
||||
default:
|
||||
//fugue_logger_warn("opendir : unsupported attribute ")
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* error handling */
|
||||
memcpy(dirent, &dirent_backup, sizeof(fugue_dir_t));
|
||||
memset(file, 0x00, sizeof(fugue_file_t));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* fugue_fs_closedir() : closedir-like function */
|
||||
int fugue_fs_closedir(fugue_dir_t *dir)
|
||||
{
|
||||
if (dir == NULL)
|
||||
return -1;
|
||||
memset(dir, 0x00, sizeof(fugue_dir_t));
|
||||
dir->current_dir_addr = 0x00000000;
|
||||
dir->cluster_addr = 0x00000000;
|
||||
dir->cluster_size = 0;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/fugue/sector.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
#include "fsctl/fugue/fat.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fugue_fs_mount() : try to initialize the FS */
|
||||
int fugue_fs_mount(fugue_fs_t *fsinfo, void *addr)
|
||||
{
|
||||
fugue_fs_t fs;
|
||||
struct fugue_fat_vbr *vbr;
|
||||
uintptr_t FAT0_addr;
|
||||
uintptr_t FAT1_addr;
|
||||
int CountofClusters;
|
||||
int RootDirSectors;
|
||||
int TotCapacity;
|
||||
int DataSec;
|
||||
void *type;
|
||||
int FATz;
|
||||
|
||||
if (fugue_sector_is_vbr(addr) != 0)
|
||||
return -1;
|
||||
vbr = addr;
|
||||
|
||||
//---
|
||||
// determine the number of cluster
|
||||
// @note
|
||||
// - hardcoded for FAT12 and FAT16
|
||||
//---
|
||||
|
||||
RootDirSectors = FAT_WORD(vbr->BPB_RootEntCnt) * 32;
|
||||
RootDirSectors += FAT_WORD(vbr->BPB_BytsPerSec) - 1;
|
||||
RootDirSectors /= FAT_WORD(vbr->BPB_BytsPerSec);
|
||||
|
||||
DataSec = FAT_WORD(vbr->BPB_RsvdSecCnt);
|
||||
DataSec += FAT_WORD(vbr->BPB_FATSz16) * vbr->BPB_NumFATs;
|
||||
DataSec += RootDirSectors;
|
||||
DataSec = FAT_WORD(vbr->BPB_TotSec16) - DataSec;
|
||||
|
||||
CountofClusters = DataSec;
|
||||
CountofClusters /= vbr->BPB_SecPerClus;
|
||||
|
||||
TotCapacity = DataSec;
|
||||
TotCapacity *= FAT_WORD(vbr->BPB_BytsPerSec);
|
||||
|
||||
if (CountofClusters < 4085) {
|
||||
type = "FAT12";
|
||||
} else if (CountofClusters < 65525) {
|
||||
type = "FAT16";
|
||||
} else {
|
||||
type = "FAT32";
|
||||
}
|
||||
|
||||
//---
|
||||
// Analysing FAT intergrity
|
||||
// @note
|
||||
// - hardcoded for two Fugue
|
||||
// - Fugue seems use a static offset of its FAT : 5120 (10 sectors)
|
||||
// - Fugue doesn't have same sized FAT (FAT0=4608 && FAT1=512)
|
||||
//---
|
||||
|
||||
//FATz = FAT_WORD(vbr->BPB_FATSz16);
|
||||
//FATz *= FAT_WORD(vbr->BPB_BytsPerSec);
|
||||
//FATz *= vbr->BPB_NumFATs;
|
||||
FATz = 5120;
|
||||
|
||||
FAT0_addr = FAT_WORD(vbr->BPB_RsvdSecCnt);
|
||||
FAT0_addr *= FAT_WORD(vbr->BPB_BytsPerSec);
|
||||
FAT0_addr += (uintptr_t)vbr;
|
||||
|
||||
FAT1_addr = 4608;
|
||||
FAT1_addr += FAT0_addr;
|
||||
|
||||
//---
|
||||
// Save calculated information
|
||||
//---
|
||||
|
||||
memset(&fs, 0x00, sizeof(fugue_fs_t));
|
||||
fs._private.vbr = addr;
|
||||
fs.props.type = type;
|
||||
fs.props.sector_data_nb = DataSec;
|
||||
fs.props.sector_root_nb = RootDirSectors;
|
||||
fs.props.cluster_nb = CountofClusters;
|
||||
fs.props.cluster_size = vbr->BPB_SecPerClus * 512;
|
||||
fs.props.cluster_nb_sector = vbr->BPB_SecPerClus;
|
||||
fs.props.capacity = TotCapacity;
|
||||
fs.props.fats_size = FATz;
|
||||
fs.props.fat0_size = 4608;
|
||||
fs.props.fat1_size = 512;
|
||||
fs._private.fat0 = (void*)FAT0_addr;
|
||||
fs._private.fat1 = (void*)FAT1_addr;
|
||||
fs._private.root = (void*)(FAT0_addr + FATz);
|
||||
|
||||
if (fugue_fat_is_vaild(&fs) != 0)
|
||||
return -1;
|
||||
memcpy(fsinfo, &fs, sizeof(fugue_fs_t));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fsctl/menu.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int key;
|
||||
int tab;
|
||||
|
||||
rom_menu_init();
|
||||
info_menu_init();
|
||||
fat_menu_init();
|
||||
list_menu_init();
|
||||
|
||||
tab = 0;
|
||||
while (1)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
if (tab == 0) { rom_menu_display(); }
|
||||
if (tab == 1) { info_menu_display(); }
|
||||
if (tab == 2) { fat_menu_display(); }
|
||||
if (tab == 3) { list_menu_display(); }
|
||||
dupdate();
|
||||
|
||||
switch (key = getkey().key)
|
||||
{
|
||||
case KEY_F1:
|
||||
tab = 0;
|
||||
break;
|
||||
case KEY_F2:
|
||||
tab = 1;
|
||||
break;
|
||||
case KEY_F3:
|
||||
tab = 2;
|
||||
break;
|
||||
case KEY_F4:
|
||||
tab = 3;
|
||||
break;
|
||||
default:
|
||||
if (tab == 0) { rom_menu_keyboard(key); }
|
||||
if (tab == 1) { info_menu_keyboard(key); }
|
||||
if (tab == 2) { fat_menu_keyboard(key); }
|
||||
if (tab == 3) { list_menu_keyboard(key); }
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
#include "fsctl/menu.h"
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/fugue/cluster.h"
|
||||
#include "fsctl/fugue/utils.h"
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
#include "fsctl/utils/display.h"
|
||||
|
||||
//---
|
||||
// internals
|
||||
//---
|
||||
|
||||
/* internal information */
|
||||
static int clus_idx = 0;
|
||||
|
||||
/* fat_cluster_is_valid() : check cluster information */
|
||||
static int fat_cluster_is_valid(fugue_fs_t *fs, int idx)
|
||||
{
|
||||
switch (fugue_cluster_is_valid(fs, idx))
|
||||
{
|
||||
case 0:
|
||||
return C_WHITE;
|
||||
default:
|
||||
return C_RED;
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fat_menu_init() : init menu */
|
||||
void fat_menu_init(void)
|
||||
{
|
||||
clus_idx = 0;
|
||||
}
|
||||
|
||||
/* fat1_menu_display() : display menu */
|
||||
void fat_menu_display(void)
|
||||
{
|
||||
fugue_fs_t fs;
|
||||
uint16_t *table;
|
||||
int idx;
|
||||
|
||||
fs_table_dtitle();
|
||||
if (fs_table_info(&fs, NULL, NULL) != 0)
|
||||
return;
|
||||
|
||||
idx = clus_idx;
|
||||
table = fs._private.fat1;
|
||||
for (int y = 1 ; y < 18 ; y++)
|
||||
{
|
||||
_printXY(0, y, "%p", &table[idx]);
|
||||
for (int x = 0 ; x < 6 ; x++)
|
||||
{
|
||||
_lrectXY(x, y, fat_cluster_is_valid(&fs, idx));
|
||||
_lrectTextXY(x, y, FAT_WORD(table[idx]));
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fat_menu_keyboard() : handle keyboard */
|
||||
void fat_menu_keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KEY_SHIFT:
|
||||
clus_idx += 6;
|
||||
break;
|
||||
case KEY_ALPHA:
|
||||
clus_idx -= 6;
|
||||
break;
|
||||
case KEY_EXIT:
|
||||
clus_idx = 0;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
clus_idx += 6 * 17;
|
||||
break;
|
||||
case KEY_UP:
|
||||
clus_idx -= 6 * 17;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
fs_table_select_left();
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
fs_table_select_right();
|
||||
break;
|
||||
}
|
||||
if (clus_idx < 0)
|
||||
clus_idx = 0;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "fsctl/menu/info.h"
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/utils/display.h"
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* info_menu_init() : init menu */
|
||||
void info_menu_init(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* info_menu_display() : display menu */
|
||||
//TODO : logger display
|
||||
void info_menu_display(void)
|
||||
{
|
||||
fugue_fs_t fs;
|
||||
int y;
|
||||
|
||||
fs_table_dtitle();
|
||||
if (fs_table_info(&fs, NULL, NULL) != 0)
|
||||
return;
|
||||
|
||||
y = 0;
|
||||
_printXY(0, ++y, "FS type = %s", fs.props.type);
|
||||
_printXY(0, ++y, "capacity = %d", fs.props.capacity);
|
||||
_printXY(0, ++y, "cluster free = %d", fs.props.cluster_free);
|
||||
_printXY(0, ++y, "cluster used = %d", fs.props.cluster_used);
|
||||
_printXY(0, ++y, "cluster dead = %d", fs.props.cluster_dead);
|
||||
_printXY(0, ++y, "cluster errs = %d", fs.props.cluster_error);
|
||||
_printXY(0, ++y, "cluster resv = %d", fs.props.cluster_resv);
|
||||
_printXY(0, ++y, "cluster number = %d", fs.props.cluster_nb);
|
||||
_printXY(0, ++y, "cluster number = %x", fs.props.cluster_nb);
|
||||
_printXY(0, ++y, "FAT0 = %p", fs._private.fat0);
|
||||
_printXY(0, ++y, "FAT1 = %p", fs._private.fat1);
|
||||
_printXY(0, ++y, "FATs size = %d", fs.props.fats_size);
|
||||
_printXY(0, ++y, "FAT0 size = %d", fs.props.fat0_size);
|
||||
_printXY(0, ++y, "FAT1 size = %d", fs.props.fat1_size);
|
||||
_printXY(0, ++y, "Root addr = %p", fs._private.root);
|
||||
}
|
||||
|
||||
/* info_menu_keyboard() : handle keyboard */
|
||||
void info_menu_keyboard(int key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
fs_table_select_left();
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
fs_table_select_right();
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include "fsctl/menu.h"
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
#include "fsctl/utils/display.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* list_menu_init() : init menu */
|
||||
void list_menu_init(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
/* fat1_menu_display() : display menu */
|
||||
void list_menu_display(void)
|
||||
{
|
||||
fugue_dir_t dir;
|
||||
fugue_file_t file;
|
||||
int y;
|
||||
|
||||
fs_table_dtitle();
|
||||
|
||||
y = 0;
|
||||
fugue_fs_opendir(&dir);
|
||||
while (fugue_fs_readdir(&dir, &file) == 0)
|
||||
{
|
||||
_printXY(0, ++y, "(%d) %s", file.size, file.name);
|
||||
}
|
||||
fugue_fs_closedir(&dir);
|
||||
}
|
||||
|
||||
/* list_menu_keyboard() : handle keyboard */
|
||||
void list_menu_keyboard(int key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
fs_table_select_left();
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
fs_table_select_right();
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
#include "fsctl/menu.h"
|
||||
#include "fsctl/fugue.h"
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
#include "fsctl/utils/display.h"
|
||||
|
||||
//---
|
||||
// internals
|
||||
//---
|
||||
|
||||
/* internal information */
|
||||
static uintptr_t addr_base;
|
||||
static uintptr_t addr_test;
|
||||
|
||||
/* sector_is_vbr() : check VBR validity */
|
||||
static int sector_is_vbr(int *color, struct fugue_fat_vbr *vbr)
|
||||
{
|
||||
fugue_fs_t fs;
|
||||
|
||||
if (fugue_fs_mount(&fs, vbr) == 0) {
|
||||
*color = C_GREEN;
|
||||
fs_table_update(&fs);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sector_is_unused() : check if the sector has been erased */
|
||||
static int sector_is_unused(int *color, uint32_t *addr)
|
||||
{
|
||||
for (int i = 0 ; i < 512 / 4 ; i++) {
|
||||
if (addr[i] != 0xffffffff)
|
||||
return -1;
|
||||
}
|
||||
*color = C_RED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sector_check() : check various operation on sector */
|
||||
static int sector_check(void *addr)
|
||||
{
|
||||
int color;
|
||||
|
||||
if (
|
||||
sector_is_unused(&color, addr) != 0
|
||||
&& sector_is_vbr(&color, addr) != 0
|
||||
)
|
||||
return C_WHITE;
|
||||
return color;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* rom_menu_init() : init menu */
|
||||
void rom_menu_init(void)
|
||||
{
|
||||
/* skip first 16Mo (OS stuff) */
|
||||
addr_base = 0xa1000000;
|
||||
addr_test = 0xa1000000;
|
||||
}
|
||||
|
||||
/* rom_menu_display() : display menu */
|
||||
void rom_menu_display(void)
|
||||
{
|
||||
addr_test = addr_base;
|
||||
for (int y = 0 ; y < 18 ; y++)
|
||||
{
|
||||
_printXY(0, y, "%p", addr_test);
|
||||
for (int x = 0 ; x < 25 ; x++)
|
||||
{
|
||||
_rectXY(x, y, sector_check((void *)addr_test));
|
||||
addr_test += 512;
|
||||
if (addr_test >= 0xa2000000)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rom_menu_keyboard() : handle keyboard */
|
||||
void rom_menu_keyboard(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case KEY_DOWN:
|
||||
addr_base += 25 * 512;
|
||||
break;
|
||||
case KEY_UP:
|
||||
addr_base -= 25 * 512;
|
||||
break;
|
||||
case KEY_EXIT:
|
||||
addr_base = 0xa0000000;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
addr_base += 25 * 18 * 512;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
addr_base -= 25 * 18 * 512;
|
||||
break;
|
||||
}
|
||||
if (addr_base < 0xa0000000)
|
||||
addr_base = 0xa0000000;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gint/display.h>
|
||||
|
||||
#include "fsctl/utils/fs_table.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* fs_table_list : FS table list */
|
||||
static struct {
|
||||
fs_table_t *table;
|
||||
int idx;
|
||||
int slots;
|
||||
} fs_table;
|
||||
|
||||
/* fs_table_append() : append the new vbr information */
|
||||
static int fs_table_append(fugue_fs_t *fs)
|
||||
{
|
||||
fs_table_t *check;
|
||||
|
||||
check = reallocarray(
|
||||
fs_table.table,
|
||||
fs_table.slots + 1,
|
||||
sizeof(fs_table_t)
|
||||
);
|
||||
if (check == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy(&check[fs_table.slots].fs, fs, sizeof(fugue_fs_t));
|
||||
fs_table.table = check;
|
||||
fs_table.slots = fs_table.slots + 1;
|
||||
if (fs_table.idx < 0)
|
||||
fs_table.idx = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fs_table_init() : initialize FS table */
|
||||
void fs_table_init(void)
|
||||
{
|
||||
fs_table.table = NULL;
|
||||
fs_table.idx = -1,
|
||||
fs_table.slots = 0;
|
||||
}
|
||||
|
||||
/* fs_table_update() : try to update internal fs table */
|
||||
int fs_table_update(fugue_fs_t *fs)
|
||||
{
|
||||
for (int i = 0 ; i < fs_table.slots ; i++)
|
||||
{
|
||||
if (fs_table.table[i].fs._private.vbr == fs->_private.vbr)
|
||||
return 0;
|
||||
}
|
||||
return fs_table_append(fs);
|
||||
}
|
||||
|
||||
/* fs_table_info() : get fs table information */
|
||||
int fs_table_info(fugue_fs_t *fs, int *fs_idx, int *nb_fs)
|
||||
{
|
||||
if (fs_table.table == NULL)
|
||||
return -1;
|
||||
if (fs != NULL)
|
||||
memcpy(fs, &fs_table.table[fs_table.idx].fs, sizeof(fugue_fs_t));
|
||||
if (fs_idx != NULL)
|
||||
*fs_idx = fs_table.idx;
|
||||
if (nb_fs != NULL)
|
||||
*nb_fs = fs_table.slots;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fs_table_dtitle() : display FS table title menu */
|
||||
void fs_table_dtitle(void)
|
||||
{
|
||||
fugue_fs_t *fs;
|
||||
|
||||
if (fs_table.table == NULL)
|
||||
{
|
||||
dprint(2, 2, C_BLACK, "No File System found");
|
||||
drect(0, 0, DWIDTH, 14, C_INVERT);
|
||||
return;
|
||||
}
|
||||
|
||||
fs = &fs_table.table[fs_table.idx].fs;
|
||||
dprint(2, 2, C_BLACK, "VBR: %p", fs->_private.vbr);
|
||||
dprint_opt(
|
||||
DWIDTH, 2,
|
||||
C_BLACK, C_NONE,
|
||||
DTEXT_RIGHT, DTEXT_TOP,
|
||||
"%d/%d",
|
||||
fs_table.idx + 1,
|
||||
fs_table.slots
|
||||
);
|
||||
drect(0, 0, DWIDTH, 13, C_INVERT);
|
||||
}
|
||||
|
||||
/* fs_table_select() : select a FS if available */
|
||||
int fs_table_select(int idx)
|
||||
{
|
||||
if (fs_table.table == NULL)
|
||||
return -1;
|
||||
if (idx >= fs_table.slots)
|
||||
return -2;
|
||||
fs_table.idx = idx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fs_table_select_left() : try to change to the idx - 1 */
|
||||
int fs_table_select_left(void)
|
||||
{
|
||||
return fs_table_select(fs_table.idx - 1);
|
||||
}
|
||||
|
||||
/* fs_table_select_right() : try to change to the idx + 1 */
|
||||
int fs_table_select_right(void)
|
||||
{
|
||||
return fs_table_select(fs_table.idx + 1);
|
||||
}
|
Loading…
Reference in New Issue