Files
stevia/include/fat32/FAT32_SYS.nasm

160 lines
5.2 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; Copyright (C) 2025 Elaina Claus
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
%ifndef __INC_FAT32_SYS
%include "partition_table.inc"
%include "fat32/bpb_offset_bx.inc"
%include "fat32/fat32_structures.inc"
; Prototyping for now...
; TODO:
; - bio_read_sectors (BIOS int13h LBA or CHS) + tiny sector cache.
; - mount: parse BPB, derive fat0_lba, data_lba, cluster0_lba.
; - FAT read: fat32_read_fat, fat32_next_clus.
; - dir iterator (SFN only) + path lookup.
; - file reader (fopen/fread) with cluster crossing.
; - contiguity probe for speed (optional).
; - (later) LFN support & code page handling.
; keep count <= 127
; int bio_read_sectors(uint64_t lba, uint16_t count, void* dst);
; will also need a bio_bios_int13h() (refactor ext_disk_read?)
; to abstract the backend 'sector getter'
; Error codes
; FS_OK 0
; FS_E_IO 1 (bio read failed)
; FS_E_FMT 2 (not FAT32 or bad BPB)
; FS_E_RANGE 3 (bad cluster or out of range)
; FS_E_END 4 (iterator end)
; FS_E_NOSUCH 5 (file/dir not found)
; FS_E_ISDIR 6 (opened dir as file)
; FS_E_TOOLONG 7 (path segment too long for 8.3)
; FS_E_UNSUPPORTED 8 (LFN present but disabled)
; FS_E_UNIMPLEMENTED 0xffff (procedure call unimplmented)
;
; Cache methods
;
; TODO: make a cache for ~4-8 disk sectors
; TODO: make a cache for FATs to avoid having to re-read the FAT
;
; // uses bio_read_sectors + cache
; int cache_read_sector(uint64_t lba, void* dst);
; int cache_invalidate_all(void);
; what a 'mount' should probably do at this point...
; - read VBR at partition_lba
; - validate FAT32 signatures
; - fill fat32_bpb_t and compute derived fields
; - read FSInfo (free count/next free)
; - ???
; int fat32_mount(uint32_t partition_lba, fat32_bpb_t* out);
;
; Accessors
;
; // Convert cluster -> LBA of first sector of that cluster
; uint64_t clus_to_lba(const fat32_bpb_t* v, uint32_t clus) {
; return v->data_lba + (uint64_t)(clus - 2) * v->secs_per_clus;
; }
; FAT32 entry is 32-bits; only low 28 bits are meaningful.
; EOC if (val & 0x0FFFFFFF) >= 0x0FFFFFF8.
; bad if == 0x0FFFFFF7.
; free if == 0x00000000.
; // Read 32-bit FAT entry for cluster n
; int fat32_read_fat(const fat32_bpb_t* v, uint32_t clus, uint32_t* out);
; // Walk to next cluster in chain (validates EOC/bad)
; int fat32_next_clus(const fat32_bpb_t* v, uint32_t clus, uint32_t* out_next);
;
; SFN directories
;
; typedef struct {
; char name83[12]; // "FILENAMEEXT" (no dot), NUL-terminated
; uint8_t attr; // ATTR_DIRECTORY=0x10, ATTR_VOLUME=0x08
; uint32_t first_clus; // (hi<<16)|lo
; uint32_t size; // bytes
; } fat32_dirent_sfn_t;
; typedef struct { // iterator
; fat32_bpb_t* v;
; uint32_t cur_clus;
; uint32_t offs_in_clus; // byte offset
; } fat32_dir_iter_t;
;int fat32_dir_iter_open_root(fat32_bpb_t* v, fat32_dir_iter_t* it);
;int fat32_dir_iter_open(fat32_bpb_t* v, uint32_t first_clus, fat32_dir_iter_t* it);
;int fat32_dir_iter_next(fat32_dir_iter_t* it, fat32_dirent_sfn_t* out); // FS_OK or FS_E_END
; typedef struct {
; uint32_t first_clus;
; uint32_t size;
; uint8_t attr; // dir or file
; } fat32_node_t;
; split by / or \.
; start at root (v->root_clus).
; for each component:
; iterate directory with dir_iter_* to find case-insensitive 8.3 match (fold to upper and space-pad during compare).
; if final component: return files cluster & size.
; if intermediate: ensure ATTR_DIRECTORY and descend.
;
; int fat32_path_lookup(fat32_bpb_t* v, const char* path, fat32_node_t* out);
; an example 'do the thing' proc to load a file to a location
;
; // loads file at path into dst, up to max_bytes; returns size read.
; int fat32_load_file(fat32_bpb_t* v, const char* path, void* dst,
; uint32_t max_bytes, uint32_t* out_size);
; streamed reads
;
; typedef struct {
; fat32_bpb_t* v;
; uint32_t first_clus;
; uint32_t cur_clus;
; uint32_t cur_clus_index; // which cluster within file were on
; uint32_t size; // total bytes
; uint32_t pos; // current byte position
; } fat32_file_t;
;
;
; int fat32_fopen(fat32_bpb_t* v, const char* path, fat32_file_t* f);
; int fat32_fread(fat32_file_t* f, void* dst, uint32_t nbytes, uint32_t* out_read);
; int fat32_fseek(fat32_file_t* f, uint32_t new_pos); // forward seeks only is fine
; int fat32_fclose(fat32_file_t* f);
; an example 'do the thing' proc to load a file to a location
;
; // loads file at path into dst, up to max_bytes; returns size read.
; int fat32_load_file(fat32_bpb_t* v, const char* path, void* dst,
; uint32_t max_bytes, uint32_t* out_size);
%endif
%define __INC_FAT32_SYS