#ifndef _FAT16_H #define _FAT16_H #include #include #include #define FAT16_MAX_FILENAME 12 /* 8.3 + null */ #define SECTOR_SIZE 512 typedef struct { uint16_t bytes_per_sector; uint8_t sectors_per_cluster; uint16_t reserved_sector_count; uint8_t num_fats; uint16_t root_entry_count; uint16_t total_sectors_16; uint16_t sectors_per_fat; uint32_t fat_start_lba; uint32_t root_dir_lba; uint32_t data_start_lba; uint32_t total_sectors; } fat16_fs_t; typedef struct { char name[FAT16_MAX_FILENAME]; /* 8.3 format */ uint8_t attr; uint16_t first_cluster; uint32_t size; } fat16_file_t; int fat16_mount(uint8_t drive); int fat16_find_file(const char* name, fat16_file_t* out_file); int fat16_create_file(const char* name, fat16_file_t* out_file); int fat16_delete_file(const char* filename); int fat16_read_file(fat16_file_t* file, void* buffer); int fat16_write_file(fat16_file_t* file, const void* buffer, uint32_t size); /* Small helper function that converts a normal filename like "test.txt" into FAT16 8.3 uppercase format padded with spaces. This makes creating and writing files much easier. */ static void filename_to_83(const char* input, char out[12]) { memset(out, ' ', 11); out[11] = '\0'; /* Find dot */ const char* dot = strchr(input, '.'); size_t name_len = dot ? (size_t) (dot - input) : strlen(input); if (name_len > 8) { name_len = 8; } for (size_t i = 0; i < name_len; i++) { out[i] = toupper((unsigned char)input[i]); } if (dot) { size_t ext_len = strlen(dot + 1); if (ext_len > 3) ext_len = 3; for (size_t i = 0; i < ext_len; i++) { out[8 + i] = toupper((unsigned char)dot[1 + i]); } } } #endif