diff options
author | Javier <dev.git@javispedro.com> | 2022-04-30 15:58:39 +0200 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2022-04-30 15:58:39 +0200 |
commit | 4a852e27302524b6ae93cca256b690d6dea80435 (patch) | |
tree | c593121f8975d9c7a6d3de28c3989fb82e5af055 /unixtime.h | |
parent | 11d69ee443a869740102d53eb292598c8d159ff6 (diff) | |
download | vbados-4a852e27302524b6ae93cca256b690d6dea80435.tar.gz vbados-4a852e27302524b6ae93cca256b690d6dea80435.zip |
support setting file date/time from dos
Diffstat (limited to 'unixtime.h')
-rw-r--r-- | unixtime.h | 64 |
1 files changed, 64 insertions, 0 deletions
@@ -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 |