diff --git a/plat/msdos86/include/ack/plat.h b/plat/msdos86/include/ack/plat.h index a1e942cdd..4343f1cf8 100644 --- a/plat/msdos86/include/ack/plat.h +++ b/plat/msdos86/include/ack/plat.h @@ -7,6 +7,5 @@ #define _ACK_PLAT_H #define ACKCONF_WANT_O_TEXT_O_BINARY 1 -#define ACKCONF_WANT_EMULATED_TIME 0 #endif diff --git a/plat/msdos86/libsys/gettimeofday.c b/plat/msdos86/libsys/gettimeofday.c new file mode 100644 index 000000000..5cea28f0f --- /dev/null +++ b/plat/msdos86/libsys/gettimeofday.c @@ -0,0 +1,92 @@ +/* $Source$ + * $State$ + * $Revision$ + */ + +/* + * Derived from dos-gettimeofday.c for newlib-ia16 which was written for the + * gcc-ia16 toolchain. + * + * Copyright (c) 2017--2021 TK Chia + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ + +#include +#include +#include +#include +#include "libsys.h" + +extern long _timezone; +extern int _daylight; + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + static volatile bool tzinited = false; + struct _dosdate dosdt, olddt; + struct _dostime dostm; + suseconds_t usec; + struct tm tm; + time_t tim; + + if (!tzinited) + { + tzset(); + tzinited = true; + } + + memset(&tm, 0, sizeof tm); + + _sys_getdate(&dosdt); + do + { + uint8_t hour; + + _sys_gettime(&dostm); + tm.tm_hour = hour = dostm.hour; + tm.tm_min = dostm.minute; + tm.tm_sec = dostm.second; + usec = dostm.hsecond * 10000UL; + + /* If the time is close to midnight, read the date again to + * check for midnight crossover. If crossover happens, + * repeat until it stops. */ + if (hour) + break; + + olddt = dosdt; + _sys_getdate(&dosdt); + } while (dosdt.day != olddt.day); + + tm.tm_year = dosdt.year - 1900; + tm.tm_mon = dosdt.month - 1; + tm.tm_mday = dosdt.day; + tm.tm_isdst = -1; + + tim = mktime(&tm); + if (tim == -1) + return -1; + + if (tv) + { + tv->tv_sec = tim; + tv->tv_usec = usec; + } + + if (tz) + { + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} diff --git a/plat/msdos86/libsys/libsys.h b/plat/msdos86/libsys/libsys.h index 3488c332e..e6aad45de 100644 --- a/plat/msdos86/libsys/libsys.h +++ b/plat/msdos86/libsys/libsys.h @@ -41,6 +41,21 @@ extern struct _fdmodes _sys_fdmodes; #define _FDVECMASK (sizeof(_fdvec_t) * CHAR_BIT - 1) +/* Structures for getting MS-DOS's idea of the current date and time. */ + +struct _dosdate { + uint8_t day; + uint8_t month; + uint16_t year; +}; + +struct _dostime { + uint8_t minute; + uint8_t hour; + uint8_t hsecond; + uint8_t second; +}; + extern int _sys_getmode(int); extern int _sys_setmode(int, int); extern int _sys_iseof(int); @@ -53,6 +68,7 @@ extern int _sys_exists(const char *); extern int _sys_rawcreat(const char *, unsigned); extern int _sys_rawopen(const char *, int); extern off_t _sys_rawlseek(int, off_t, int); - +extern void _sys_getdate(struct _dosdate *); +extern void _sys_gettime(struct _dostime *); #endif diff --git a/plat/msdos86/libsys/sys_getdate.s b/plat/msdos86/libsys/sys_getdate.s new file mode 100644 index 000000000..41d69fc85 --- /dev/null +++ b/plat/msdos86/libsys/sys_getdate.s @@ -0,0 +1,25 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Get the current system date from MS-DOS. + +.define __sys_getdate +__sys_getdate: + movb ah, 0x2a + int 0x21 + mov bx, sp + mov bx, 2(bx) + mov (bx), dx + mov 2(bx), cx + ret diff --git a/plat/msdos86/libsys/sys_gettime.s b/plat/msdos86/libsys/sys_gettime.s new file mode 100644 index 000000000..d062fad8d --- /dev/null +++ b/plat/msdos86/libsys/sys_gettime.s @@ -0,0 +1,25 @@ +# +! $Source$ +! $State$ +! $Revision$ + +! Declare segments (the order is important). + +.sect .text +.sect .rom +.sect .data +.sect .bss + +.sect .text + +! Get the current system time from MS-DOS. + +.define __sys_gettime +__sys_gettime: + movb ah, 0x2c + int 0x21 + mov bx, sp + mov bx, 2(bx) + mov (bx), cx + mov 2(bx), dx + ret