plat/msdos86: add gettimeofday( )

This commit is contained in:
Tee-Kiah Chia 2021-03-29 15:15:13 +00:00
parent f2c8828a4b
commit a6c7ac2a28
5 changed files with 159 additions and 2 deletions

View file

@ -7,6 +7,5 @@
#define _ACK_PLAT_H #define _ACK_PLAT_H
#define ACKCONF_WANT_O_TEXT_O_BINARY 1 #define ACKCONF_WANT_O_TEXT_O_BINARY 1
#define ACKCONF_WANT_EMULATED_TIME 0
#endif #endif

View file

@ -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 <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
#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;
}

View file

@ -41,6 +41,21 @@ extern struct _fdmodes _sys_fdmodes;
#define _FDVECMASK (sizeof(_fdvec_t) * CHAR_BIT - 1) #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_getmode(int);
extern int _sys_setmode(int, int); extern int _sys_setmode(int, int);
extern int _sys_iseof(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_rawcreat(const char *, unsigned);
extern int _sys_rawopen(const char *, int); extern int _sys_rawopen(const char *, int);
extern off_t _sys_rawlseek(int, off_t, int); extern off_t _sys_rawlseek(int, off_t, int);
extern void _sys_getdate(struct _dosdate *);
extern void _sys_gettime(struct _dostime *);
#endif #endif

View file

@ -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

View file

@ -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