aboutsummaryrefslogtreecommitdiff
path: root/unixtime.h
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-04-30 15:58:39 +0200
committerJavier <dev.git@javispedro.com>2022-04-30 15:58:39 +0200
commit4a852e27302524b6ae93cca256b690d6dea80435 (patch)
treec593121f8975d9c7a6d3de28c3989fb82e5af055 /unixtime.h
parent11d69ee443a869740102d53eb292598c8d159ff6 (diff)
downloadvbados-4a852e27302524b6ae93cca256b690d6dea80435.tar.gz
vbados-4a852e27302524b6ae93cca256b690d6dea80435.zip
support setting file date/time from dos
Diffstat (limited to 'unixtime.h')
-rw-r--r--unixtime.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/unixtime.h b/unixtime.h
index 296c8ac..57846b7 100644
--- a/unixtime.h
+++ b/unixtime.h
@@ -150,4 +150,68 @@ static void timestampns_to_dos_time(uint16_t __far *dos_time, uint16_t __far *do
*dos_date = ((year << 9) & 0xFE00) | ((month << 5) & 0x1E0) | (day & 0x1F);
}
+static void timestampns_from_dos_time(int64_t *timestampns, uint16_t dos_time, uint16_t dos_date, int32_t tzoffset)
+{
+ unsigned year = (dos_date & 0xFE00) >> 9,
+ month = (dos_date & 0x1E0) >> 5,
+ day = (dos_date & 0x1F),
+ hours = (dos_time & 0xF800) >> 11,
+ minutes = (dos_time & 0x7E0) >> 5,
+ seconds2 = (dos_time & 0x1F);
+ long days_since_epoch = 0;
+ long seconds2_since_day;
+ bool is_leap;
+
+ year += DOS_EPOCH_YEAR;
+ is_leap = is_leap_year(year);
+
+ while (year > UNIX_EPOCH_YEAR) {
+ days_since_epoch += days_per_year(--year);
+ }
+ while (year < UNIX_EPOCH_YEAR) {
+ days_since_epoch -= days_per_year(year++);
+ }
+
+ while (month > 1) {
+ days_since_epoch += days_per_month(--month, is_leap);
+ }
+ days_since_epoch += day - 1;
+
+ seconds2_since_day = seconds2 + (minutes * 60U/2) + (hours * 3600U/2);
+
+ dlog_print("days_since_epoch=");
+ dlog_printd(days_since_epoch);
+ dlog_print(" seconds2_since_day=");
+ dlog_printd(seconds2_since_day);
+ dlog_endline();
+
+ __asm {
+ push eax
+ push ecx
+ push edx
+
+ mov eax, [days_since_epoch]
+ mov ecx, (24 * 60 * 60) / 2 /* seconds in one day / 2 */
+
+ imul eax, ecx
+
+ add eax, [seconds2_since_day]
+ /* eax now contains seconds_since_epoch / 2 */
+
+ add eax, [tzoffset] /* Add tzoffset now (which is in seconds / 2 units) */
+
+ mov ecx, 2 * 1000000000 /* nanoseconds in 2 seconds, should still fit in a dword */
+
+ imul ecx /* 64-bit signed multiply eax * ecx, returns result in edx:eax */
+
+ mov si, [timestampns]
+ mov dword ptr [si], eax
+ mov dword ptr [si + 4], edx
+
+ pop edx
+ pop ecx
+ pop eax
+ }
+}
+
#endif // UNIXTIME_H