mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
Some time manipulation. Added the targets to the .gitignore file.
This commit is contained in:
parent
1f223f807f
commit
58db663ae6
19 changed files with 268 additions and 71 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -10,3 +10,8 @@ build/**
|
|||
|
||||
# Some notes.
|
||||
LIBC
|
||||
|
||||
# Output files
|
||||
libc.a
|
||||
libgint.a
|
||||
gintdemo.g1a
|
||||
|
|
2
Makefile
2
Makefile
|
@ -14,7 +14,7 @@
|
|||
# Modules
|
||||
modules-gint = core keyboard mmu mpu rtc screen timer \
|
||||
bopti display gray tales
|
||||
modules-libc = setjmp string stdio stdlib
|
||||
modules-libc = setjmp string stdio stdlib time
|
||||
|
||||
# Targets
|
||||
target-g1a = gintdemo.g1a
|
||||
|
|
|
@ -38,7 +38,7 @@ register access and implements a few standard functions.
|
|||
Building and installing
|
||||
-----------------------
|
||||
|
||||
There a some dependencies:
|
||||
There are some dependencies:
|
||||
* The `sh3eb-elf` toolchain somewhere in the PATH
|
||||
* The fxSDK installed and available in the PATH
|
||||
|
||||
|
|
3
TODO
3
TODO
|
@ -18,11 +18,10 @@
|
|||
+ partial transparency
|
||||
+ gint vs. ML with 248x124 at (-60, -28)
|
||||
+ call exit handlers
|
||||
+ compute frequencies
|
||||
+ compute frequencies and CLOCKS_PER_SEC
|
||||
+ test all font encodings
|
||||
|
||||
- improve exception handler debugging information (if possible)
|
||||
- full rtc driver (time)
|
||||
- callbacks and complete user API
|
||||
|
||||
~ packed bit fields
|
||||
|
|
BIN
gintdemo.g1a
BIN
gintdemo.g1a
Binary file not shown.
16
include/internals/time.h
Normal file
16
include/internals/time.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _INTERNALS_TIME_H
|
||||
#define _INTERNALS_TIME_H 1
|
||||
|
||||
/*
|
||||
isLeap()
|
||||
Determines whether the given year is a leap year.
|
||||
*/
|
||||
int isLeap(int year);
|
||||
|
||||
/*
|
||||
daysInMonth()
|
||||
Returns number of days for the given month (between 0 and 11) and year.
|
||||
*/
|
||||
int daysInMonth(int month, int year);
|
||||
|
||||
#endif // _INTERNALS_TIME_H
|
|
@ -15,9 +15,7 @@
|
|||
|
||||
/*
|
||||
struct RTCTime
|
||||
Defines a point in time. This structure *is* the standard struct tm to
|
||||
avoid useless data copy in the interface between this module and the
|
||||
standard time module.
|
||||
Defines a point in time.
|
||||
*/
|
||||
struct RTCTime
|
||||
{
|
||||
|
@ -26,21 +24,21 @@ struct RTCTime
|
|||
int hours; // Hours in range 0-23
|
||||
int month_day; // Day of month in range 1-31
|
||||
int month; // Month in range 0-11
|
||||
int year; // Number of years since 1900
|
||||
int year; // Years (full value)
|
||||
int week_day; // Day of week in range 0(Sunday)-6(Saturday).
|
||||
int year_day; // Day of the year in range 0-365.
|
||||
int daylight_saving; // As far as I known the RTC does not use DST.
|
||||
};
|
||||
|
||||
/*
|
||||
rtc_getTime()
|
||||
Reads the current time from the RTC.
|
||||
Reads the current time from the RTC. There is no guarantee that the
|
||||
week day is correct (use the time API for that).
|
||||
*/
|
||||
struct RTCTime rtc_getTime(void);
|
||||
|
||||
/*
|
||||
rtc_setTime()
|
||||
Sets the time in the RTC registers.
|
||||
Sets the time in the RTC registers. The week day is set to 0 if greater
|
||||
than 6. Other fields are not checked.
|
||||
*/
|
||||
void rtc_setTime(struct RTCTime time);
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ struct tm
|
|||
int tm_year; // Number of years since 1900
|
||||
int tm_wday; // Day of week in range 0(Sunday)-6(Saturday).
|
||||
int tm_yday; // Day of the year in range 0-365.
|
||||
int tm_isdst; // Always -1 (not available).
|
||||
int tm_isdst; // This will always be 0.
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -57,6 +57,17 @@ typedef signed int time_t;
|
|||
*/
|
||||
clock_t clock(void);
|
||||
|
||||
/*
|
||||
time()
|
||||
Returns the current time as calendar time. If you need a broken-down
|
||||
time, either use the RTC API or gmtime(). However, this function is
|
||||
already based on mktime() (for hardware reasons) so it would be much
|
||||
faster to use the RTC API if possible.
|
||||
If timeptr is not NULL, it is set to the current time, that is, the
|
||||
value that is returned.
|
||||
*/
|
||||
time_t time(time_t *timeptr);
|
||||
|
||||
/*
|
||||
difftime()
|
||||
Returns the number of seconds between the given points.
|
||||
|
@ -71,15 +82,45 @@ double difftime(time_t end, time_t beginning);
|
|||
// Time representation.
|
||||
//---
|
||||
|
||||
/*
|
||||
asctime()
|
||||
Converts broken-down time to string representation on the form
|
||||
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||
allocated and may be overwritten by any subsequent call to a time
|
||||
function.
|
||||
*/
|
||||
char *asctime(const struct tm *time);
|
||||
|
||||
/*
|
||||
ctime()
|
||||
Converts calendar time to string representation on the form
|
||||
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||
allocated and may be overwritten by any subsequent call to a time
|
||||
function.
|
||||
*/
|
||||
char *ctime(const time_t *timer);
|
||||
|
||||
|
||||
|
||||
//---
|
||||
//
|
||||
// Time conversion.
|
||||
//---
|
||||
|
||||
/*
|
||||
mktime()
|
||||
Computes fields tm_wday and tm_yday using the other fields. Member
|
||||
structures outside their range are normalized and tm_isdst is set.
|
||||
Converts broken-down time to calendar time. Computes structure fields
|
||||
tm_wday and tm_yday using the other fields. Member structures outside
|
||||
their range are normalized (e.g. 40 October becomes 9 November) and
|
||||
tm_isdst is set.
|
||||
*/
|
||||
time_t mktime(struct tm *time);
|
||||
|
||||
/*
|
||||
gmtime()
|
||||
Converts calendar time to broken-down time. The returned pointer is
|
||||
statically allocated and may be overwritten by any subsequent call to
|
||||
a time function.
|
||||
*/
|
||||
struct tm *gmtime(const time_t *t);
|
||||
|
||||
#endif // _TIME_H
|
||||
|
|
BIN
libc.a
BIN
libc.a
Binary file not shown.
BIN
libgint.a
BIN
libgint.a
Binary file not shown.
|
@ -16,23 +16,11 @@ static int integer16(int bcd)
|
|||
+ 1000 * (bcd >> 12);
|
||||
}
|
||||
|
||||
static int year_day(int year, int year_bcd, int month, int month_day)
|
||||
{
|
||||
int days_in_month[12] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
int leap;
|
||||
int hundreds = integer8(year_bcd >> 8);
|
||||
int day, i;
|
||||
|
||||
leap = !(year & 3); // Take multiples of 4
|
||||
if(!((year_bcd >> 8) & 0xf)) leap = 0; // Remove multiples of 100
|
||||
if(!(hundreds & 3)) leap = 1; // Take multiples of 400
|
||||
|
||||
day = leap && (month > 2);
|
||||
for(i = 0; i < month - 1; i++) day += days_in_month[i];
|
||||
return day + month_day - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_getTime()
|
||||
Reads the current time from the RTC. There is no guarantee that the
|
||||
week day is correct (use the time API for that).
|
||||
*/
|
||||
struct RTCTime rtc_getTime(void)
|
||||
{
|
||||
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||
|
@ -43,11 +31,8 @@ struct RTCTime rtc_getTime(void)
|
|||
time.hours = integer8(rtc->RHRCNT.BYTE);
|
||||
time.month_day = integer8(rtc->RDAYCNT.BYTE);
|
||||
time.month = integer8(rtc->RMONCNT.BYTE);
|
||||
time.year = integer16(rtc->RYRCNT.WORD) - 1900;
|
||||
time.year = integer16(rtc->RYRCNT.WORD);
|
||||
time.week_day = rtc->RWKCNT;
|
||||
time.year_day = year_day(time.year + 1900, rtc->RYRCNT.WORD,
|
||||
time.month, time.month_day);
|
||||
|
||||
time.daylight_saving = 0;
|
||||
return time;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,11 @@ static int bcd16(int integer)
|
|||
return (bcd8(integer / 100) << 8) | bcd8(integer % 100);
|
||||
}
|
||||
|
||||
/*
|
||||
rtc_setTime()
|
||||
Sets the time in the RTC registers. The week day is set to 0 if greater
|
||||
than 6. Other fields are not checked.
|
||||
*/
|
||||
void rtc_setTime(struct RTCTime time)
|
||||
{
|
||||
volatile struct mod_rtc *rtc = isSH3() ? RTC_SH7705 : RTC_SH7305;
|
||||
|
@ -26,6 +31,6 @@ void rtc_setTime(struct RTCTime time)
|
|||
rtc->RHRCNT.BYTE = bcd8(time.hours);
|
||||
rtc->RDAYCNT.BYTE = bcd8(time.month_day);
|
||||
rtc->RMONCNT.BYTE = bcd8(time.month);
|
||||
rtc->RYRCNT.WORD = bcd16(time.year + 1900);
|
||||
rtc->RYRCNT.WORD = bcd16(time.year);
|
||||
rtc->RWKCNT = time.week_day < 7 ? time.week_day : 0;
|
||||
}
|
||||
|
|
57
src/time/asctime.c
Normal file
57
src/time/asctime.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <time.h>
|
||||
|
||||
static char str[26];
|
||||
|
||||
/*
|
||||
asctime()
|
||||
Converts broken-down time to string representation on the form
|
||||
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||
allocated and may be overwritten by any subsequent call to a time
|
||||
function.
|
||||
*/
|
||||
char *asctime(const struct tm *time)
|
||||
{
|
||||
const char *days[] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
}, *months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
|
||||
"Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
int year = time->tm_year + 1900;
|
||||
|
||||
str[0] = days[time->tm_wday][0];
|
||||
str[1] = days[time->tm_wday][1];
|
||||
str[2] = days[time->tm_wday][2];
|
||||
str[3] = ' ';
|
||||
|
||||
str[4] = months[time->tm_mon][0];
|
||||
str[5] = months[time->tm_mon][1];
|
||||
str[6] = months[time->tm_mon][2];
|
||||
str[7] = ' ';
|
||||
|
||||
str[8] = '0' + (time->tm_mday / 10);
|
||||
str[9] = '0' + (time->tm_mday % 10);
|
||||
str[10] = ' ';
|
||||
|
||||
str[11] = '0' + (time->tm_hour / 10);
|
||||
str[12] = '0' + (time->tm_hour % 10);
|
||||
str[13] = ':';
|
||||
str[14] = '0' + (time->tm_min / 10);
|
||||
str[15] = '0' + (time->tm_min % 10);
|
||||
str[16] = ':';
|
||||
str[17] = '0' + (time->tm_sec / 10);
|
||||
str[18] = '0' + (time->tm_sec % 10);
|
||||
str[19] = ' ';
|
||||
|
||||
str[20] = '0' + (year / 1000);
|
||||
year %= 1000;
|
||||
str[21] = '0' + (year / 100);
|
||||
year %= 100;
|
||||
str[22] = '0' + (year / 10);
|
||||
str[23] = '0' + (year % 10);
|
||||
|
||||
str[24] = '\n';
|
||||
str[25] = 0;
|
||||
|
||||
return str;
|
||||
}
|
13
src/time/ctime.c
Normal file
13
src/time/ctime.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <time.h>
|
||||
|
||||
/*
|
||||
ctime()
|
||||
Converts calendar time to string representation on the form
|
||||
"Wed Jun 30 21:49:08 1993\n". The returned string is statically
|
||||
allocated and may be overwritten by any subsequent call to a time
|
||||
function.
|
||||
*/
|
||||
char *ctime(const time_t *timer)
|
||||
{
|
||||
return asctime(gmtime(timer));
|
||||
}
|
45
src/time/gmtime.c
Normal file
45
src/time/gmtime.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <time.h>
|
||||
#include <internals/time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static struct tm tm;
|
||||
|
||||
/*
|
||||
gmtime()
|
||||
Converts calendar time to broken-down time. The returned pointer is
|
||||
statically allocated and may be overwritten by any subsequent call to
|
||||
a time function.
|
||||
*/
|
||||
struct tm *gmtime(const time_t *timeptr)
|
||||
{
|
||||
time_t t = *timeptr;
|
||||
div_t d;
|
||||
int sec;
|
||||
|
||||
tm.tm_year = 1970;
|
||||
tm.tm_mon = 0;
|
||||
|
||||
sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600;
|
||||
while(t >= sec)
|
||||
{
|
||||
t -= sec;
|
||||
if(++tm.tm_mon == 12)
|
||||
{
|
||||
tm.tm_year++;
|
||||
tm.tm_mon = 0;
|
||||
}
|
||||
sec = daysInMonth(tm.tm_mon, tm.tm_year) * 24 * 3600;
|
||||
}
|
||||
tm.tm_year -= 1900;
|
||||
|
||||
d = div(sec, 24 * 3600);
|
||||
tm.tm_mday = d.quot;
|
||||
d = div(d.rem, 3600);
|
||||
tm.tm_hour = d.quot;
|
||||
d = div(d.rem, 60);
|
||||
tm.tm_min = d.quot;
|
||||
tm.tm_sec = d.rem;
|
||||
|
||||
mktime(&tm);
|
||||
return &tm;
|
||||
}
|
|
@ -1,42 +1,17 @@
|
|||
#include <time.h>
|
||||
|
||||
/*
|
||||
isLeap()
|
||||
Determines whether the given year is a leap year.
|
||||
*/
|
||||
int isLeap(int year)
|
||||
{
|
||||
int leap = !(year & 3); // Take multiples of 4
|
||||
if(!(year % 100)) leap = 0; // Remove multiples of 100
|
||||
if(!(year % 400)) leap = 1; // Take multiples of 400
|
||||
|
||||
return leap;
|
||||
}
|
||||
|
||||
/*
|
||||
daysInMonth()
|
||||
Returns number of days for the given month (between 0 and 11) and year.
|
||||
*/
|
||||
int daysInMonth(int month, int year)
|
||||
{
|
||||
int days[12] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
if(month != 1) return days[month];
|
||||
return days[month] + isLeap(year);
|
||||
}
|
||||
#include <internals/time.h>
|
||||
|
||||
/*
|
||||
mktime()
|
||||
Computes fields tm_wday and tm_yday using the other fields. Member
|
||||
structures outside their range are normalized and tm_isdst is set.
|
||||
Converts broken-down time to calendar time. Computes structure fields
|
||||
tm_wday and tm_yday using the other fields. Member structures outside
|
||||
their range are normalized (e.g. 40 October becomes 9 November) and
|
||||
tm_isdst is set.
|
||||
*/
|
||||
time_t mktime(struct tm *time)
|
||||
{
|
||||
int first, leaps, yr;
|
||||
int leaps, yr;
|
||||
int days, i;
|
||||
time_t elapsed;
|
||||
|
||||
// Normalizing time.
|
||||
time->tm_min += (time->tm_sec / 60);
|
||||
|
@ -88,6 +63,6 @@ time_t mktime(struct tm *time)
|
|||
// days may become negative, so add the calendar period.
|
||||
if(days < 0) days += 146097;
|
||||
|
||||
return (24 * 3600) * days + 3600 * time->tm_hour + 60 * time->tm_min +
|
||||
time->tm_sec;
|
||||
return (time_t)((24 * 3600) * days + 3600 * time->tm_hour +
|
||||
60 * time->tm_min + time->tm_sec);
|
||||
}
|
||||
|
|
29
src/time/time.c
Normal file
29
src/time/time.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <time.h>
|
||||
#include <rtc.h>
|
||||
|
||||
/*
|
||||
time()
|
||||
Returns the current time as calendar time. If you need a broken-down
|
||||
time, either use the RTC API or gmtime(). However, this function is
|
||||
already based on mktime() (for hardware reasons) so it would be much
|
||||
faster to use the RTC API if possible.
|
||||
If timeptr is not NULL, it is set to the current time, that is, the
|
||||
value that is returned.
|
||||
*/
|
||||
time_t time(time_t *timeptr)
|
||||
{
|
||||
struct RTCTime rtc = rtc_getTime();
|
||||
struct tm tm;
|
||||
time_t calendar;
|
||||
|
||||
tm.tm_sec = rtc.seconds;
|
||||
tm.tm_min = rtc.minutes;
|
||||
tm.tm_hour = rtc.hours;
|
||||
tm.tm_mday = rtc.month_day;
|
||||
tm.tm_mon = rtc.month;
|
||||
tm.tm_year = rtc.year - 1900;
|
||||
|
||||
calendar = mktime(&tm);
|
||||
if(timeptr) *timeptr = calendar;
|
||||
return calendar;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#include <time.h>
|
||||
#undef difftime
|
||||
|
||||
/*
|
||||
clock()
|
||||
|
|
28
src/time/time_util.c
Normal file
28
src/time/time_util.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <internals/time.h>
|
||||
|
||||
/*
|
||||
isLeap()
|
||||
Determines whether the given year is a leap year.
|
||||
*/
|
||||
int isLeap(int year)
|
||||
{
|
||||
int leap = !(year & 3); // Take multiples of 4
|
||||
if(!(year % 100)) leap = 0; // Remove multiples of 100
|
||||
if(!(year % 400)) leap = 1; // Take multiples of 400
|
||||
|
||||
return leap;
|
||||
}
|
||||
|
||||
/*
|
||||
daysInMonth()
|
||||
Returns number of days for the given month (between 0 and 11) and year.
|
||||
*/
|
||||
int daysInMonth(int month, int year)
|
||||
{
|
||||
int days[12] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
if(month != 1) return days[month];
|
||||
return days[month] + isLeap(year);
|
||||
}
|
Loading…
Reference in a new issue