|
@@ -2,7 +2,7 @@
|
|
|
* FAT12/16/32 Filesystem Driver
|
|
|
* main.c
|
|
|
*
|
|
|
- * Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
|
|
|
+ * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
|
|
|
*
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
@@ -123,20 +123,64 @@ static void fatfs_set_entry_name(fatfs_dirent_t *dirent, const char *name)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static inline void fatfs_pack_file_time(clock_time_t *os_time, word_t *date, word_t *time)
|
|
|
+static inline void fatfs_pack_file_time(clock_time_t os_time, word_t *date, word_t *time)
|
|
|
{
|
|
|
- if (date) *date = (os_time->year << 9) | (os_time->month << 5) | os_time->day;
|
|
|
- if (time) *time = (os_time->hours << 11) | (os_time->minutes << 5) | (os_time->seconds >> 1);
|
|
|
+ if (os_time < 0) os_time = 0;
|
|
|
+
|
|
|
+ if (date)
|
|
|
+ {
|
|
|
+ clock_time_t total_days = os_time / 86400000000LL;
|
|
|
+
|
|
|
+ int i;
|
|
|
+ for (i = 1980;; i++)
|
|
|
+ {
|
|
|
+ int year_days = (!(i % 400) || (!(i % 4) && (i % 100))) ? 366 : 365;
|
|
|
+ if (total_days < year_days) break;
|
|
|
+ total_days -= year_days;
|
|
|
+ }
|
|
|
+
|
|
|
+ *date = (i - 1980) << 9;
|
|
|
+
|
|
|
+ int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
|
+ if (!(i % 400) || (!(i % 4) && (i % 100))) month_days[1]++;
|
|
|
+ for (i = 1; i <= 12; i++)
|
|
|
+ {
|
|
|
+ if (total_days < month_days[i - 1]) break;
|
|
|
+ total_days -= month_days[i - 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ *date |= (i << 5) | total_days;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (time)
|
|
|
+ {
|
|
|
+ clock_time_t total_seconds = (os_time / 1000000) % 86400;
|
|
|
+ *time = ((total_seconds / 3600) << 11) | (((total_seconds / 60) % 60) << 5) | ((total_seconds % 60) >> 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static inline void fatfs_unpack_file_time(word_t date, word_t time, clock_time_t *os_time)
|
|
|
{
|
|
|
- os_time->day = date & 0x1F;
|
|
|
- os_time->month = (date >> 5) & 0x0F;
|
|
|
- os_time->year = (date >> 9) & 0x7F;
|
|
|
- os_time->seconds = (time & 0x1F) << 1;
|
|
|
- os_time->minutes = (time >> 5) & 0x3F;
|
|
|
- os_time->hours = (time >> 11) & 0x1F;
|
|
|
+ clock_time_t year = (date >> 9) & 0x7F;
|
|
|
+ clock_time_t month = (date >> 5) & 0x0F;
|
|
|
+ clock_time_t day = date & 0x1F;
|
|
|
+ clock_time_t hour = (time >> 11) & 0x1F;
|
|
|
+ clock_time_t minute = (time >> 5) & 0x3F;
|
|
|
+ clock_time_t second = (time & 0x1F) << 1;
|
|
|
+ clock_time_t total_days = 0;
|
|
|
+
|
|
|
+ int i;
|
|
|
+ for (i = 1980; i < 1980 + year; i++)
|
|
|
+ {
|
|
|
+ total_days += (!(i % 400) || (!(i % 4) && (i % 100))) ? 366 : 365;
|
|
|
+ }
|
|
|
+
|
|
|
+ int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
|
|
+ if (!(i % 400) || (!(i % 4) && (i % 100))) month_days[1]++;
|
|
|
+ for (i = 1; i < month; i++) total_days += month_days[i - 1];
|
|
|
+ total_days += day - 1;
|
|
|
+
|
|
|
+ *os_time = (60 * (60 * (24 * total_days + hour) + minute) + second) * 1000000;
|
|
|
}
|
|
|
|
|
|
static dword_t fatfs_get_next_cluster(fatfs_volume_t *volume, dword_t cluster)
|
|
@@ -486,7 +530,7 @@ static dword_t fatfs_resize_file(fatfs_file_t *file, qword_t new_size)
|
|
|
dirent.size = file->header.size;
|
|
|
dirent.first_cluster_low = file->first_cluster & 0xFFFF;
|
|
|
dirent.first_cluster_high = file->first_cluster >> 16;
|
|
|
- fatfs_pack_file_time(¤t_time, &dirent.modification_date, &dirent.modification_time);
|
|
|
+ fatfs_pack_file_time(current_time, &dirent.modification_date, &dirent.modification_time);
|
|
|
|
|
|
return device_write(volume->header.device,
|
|
|
&dirent,
|
|
@@ -782,9 +826,9 @@ static dword_t fatfs_load_file(file_t **_file)
|
|
|
|
|
|
fatfs_set_entry_name(&dirent, file_name);
|
|
|
dirent.duration = 1;
|
|
|
- fatfs_pack_file_time(¤t_time, &dirent.creation_date, &dirent.creation_time);
|
|
|
- fatfs_pack_file_time(¤t_time, &dirent.modification_date, &dirent.modification_time);
|
|
|
- fatfs_pack_file_time(¤t_time, &dirent.last_accessed_date, NULL);
|
|
|
+ fatfs_pack_file_time(current_time, &dirent.creation_date, &dirent.creation_time);
|
|
|
+ fatfs_pack_file_time(current_time, &dirent.modification_date, &dirent.modification_time);
|
|
|
+ fatfs_pack_file_time(current_time, &dirent.last_accessed_date, NULL);
|
|
|
dirent.first_cluster_high = 0;
|
|
|
dirent.first_cluster_low = 0;
|
|
|
dirent.size = 0;
|