Skip to content

Commit

Permalink
Ported libc time library
Browse files Browse the repository at this point in the history
Includes:
- clock() - was done previously
- difftime()
- mktime()
- time()
- localtime()
- gmtime()
- asctime()
- ctime()
  • Loading branch information
pcawte committed Jul 3, 2023
1 parent dd5ce74 commit ba44b62
Show file tree
Hide file tree
Showing 17 changed files with 1,013 additions and 5 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ In the relevant: example, test or any other directory created at the same level.

25/06/2023:

- `scanf` and sscanf moved into standard library (libc)
- `scanf` and `sscanf` moved into standard library (libc)

30/06/2023:

- bug in strncpy.src which used a ZDS pseudo op that is not implemented in fasmg assembler. Replaced by individual assembly instructions. This problem may occur in other libraries copied from ZDS. For the moment, just fixed in this one location.
- bug in `strncpy.src` which used a ZDS pseudo op that is not implemented in fasmg assembler. Replaced by individual assembly instructions. This problem may occur in other libraries copied from ZDS. For the moment, just fixed in this one location.

- C-runtime `crt0.src` updated to added back functionality previously removed as part of the proof of concept

Expand Down Expand Up @@ -135,7 +135,11 @@ In the relevant: example, test or any other directory created at the same level.

- Corrected` lib/crt/fpftol.src` to remove ZDS pseudo op not supported by fasmg and removed other ZDS assembler features that are different in fasmg

- Corrected lib/crt/fpultof.src to remover ZDS assembler directives that are different in fasmg
- Corrected `lib/crt/fpultof.src` to remove ZDS assembler directives that are different in fasmg

- Ported time functions: `difftime()`, `mktime()`, `time()`, `localtime()`, `gmtime()`, `asctime()`, `ctime()`

- Updated comments in `mos_api.h` to note that `getsysvar_rtc()` data is only updated when `mos_getrtc()` is called. This is taken account of in `time()`.

### To-Do:

Expand Down
2 changes: 1 addition & 1 deletion include/mos_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ extern uint8_t getsysvar_scrpixelIndex();
extern uint8_t getsysvar_vkeycode();
extern uint8_t getsysvar_vkeydown();
extern uint8_t getsysvar_vkeycount();
extern volatile RTC_DATA* getsysvar_rtc();
extern volatile RTC_DATA* getsysvar_rtc(); // mos_getrtc() needs to be called to update the values
extern uint16_t getsysvar_keydelay();
extern uint16_t getsysvar_keyrate();
extern uint8_t getsysvar_keyled();
Expand Down
83 changes: 83 additions & 0 deletions include/time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#ifndef _TIME_H
#define _TIME_H

#include <cdefs.h>

#ifndef LOCALTIME_GMT_OFFSET
#define LOCALTIME_GMT_OFFSET 0
#endif

#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 100UL
#endif

/* Time Types
Data Type: clock_t
------------------
clock_t is used to measure processor and CPU time. It may be an integer or a floating-point type.
Its values are counts of clock ticks since some arbitrary event in the past. The number of clock ticks
per second is system-specific.
- On Agon it is an unsigned long & ticks are in centi-seconds. It is incremented by 2 by MOS in
the vertical blanking interrupt
Data Type: time_t
-----------------
time_t is the simplest data type used to represent simple calendar time.
In ISO C, time_t can be either an integer or a floating-point type, and the meaning of time_t values
is not specified. The only things a strictly conforming program can do with time_t values are:
pass them to difftime to get the elapsed time between two simple calendar times (see Calculating Elapsed
Time), and pass them to the functions that convert them to broken-down time (see Broken-down Time).
On POSIX-conformant systems, time_t is an integer type and its values represent the number of seconds
elapsed since the epoch, which is 00:00:00 on January 1, 1970, Coordinated Universal Time.
The GNU C Library additionally guarantees that time_t is a signed type, and that all of its functions
operate correctly on negative time_t values, which are interpreted as times before the epoch.
- On Agon it is an unsigned long, representing the numer of seconds elapsed since the the epoch
Data Type: struct tm
--------------------
struct tm is a broken-down time is a binary representation of calendar time separated into year, month,
day, and so on. Broken-down time values are not useful for calculations, but they are useful for printing
human readable time information (see details in the struct definition below.
*/

typedef unsigned long time_t;
typedef unsigned long clock_t;

struct tm {
int tm_sec; // normally 0-59, can be 60 for leap-second
int tm_min; // 0-59
int tm_hour; // 0-23
int tm_mday; // 1-31 (note starts at 1, not 0)
int tm_mon; // 0-11
int tm_year; // Number of full calendar years since 1990
int tm_wday; // 0-6 (0=Sunday)
int tm_yday; // 0-365
int tm_isdst; // Daylight saving flag (+ve if in effect, 0 if not, -ve if unknown)
};

__BEGIN_DECLS

clock_t clock(void);

double difftime(time_t time1, time_t time0)
__attribute__((__const__));

time_t mktime(struct tm *tmp);

time_t time(time_t *timer);

struct tm *localtime(const time_t *timer);

struct tm *gmtime(const time_t *timer);

char *asctime(const struct tm *tmp);

char *ctime(const time_t *timer);

__END_DECLS

#endif /* _TIME_H */
224 changes: 224 additions & 0 deletions lib/libc/gmtime.c.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
section .text,"ax",@progbits
assume adl = 1
section .text,"ax",@progbits
public _gmtime
_gmtime:
ld hl, -10
call __frameset
ld iy, (ix + 6)
ld bc, 0
xor a, a
lea hl, iy
ld hl, (hl)
ld e, (iy + 3)
ld iy, 70
ld (_gmtime.tm2), bc
ld (_gmtime.tm2+3), bc
ld (_gmtime.tm2+6), bc
inc bc
ld (_gmtime.tm2+9), bc
dec bc
ld (_gmtime.tm2+12), bc
ld (_gmtime.tm2+15), iy
ld (ix - 3), hl
ld (ix - 4), e
ld bc, 86400
call __ldivu
ld.sis de, 4
add.sis hl, de
ld.sis bc, 7
call __sremu
ld de, 0
ld e, l
ld d, h
ld (_gmtime.tm2+18), de
scf
sbc hl, hl
ld (_gmtime.tm2+24), hl
BB0_1:
push iy
call _istmleap
pop hl
bit 0, a
ld bc, -1932032
jr nz, BB0_3
ld bc, -2018432
BB0_3:
bit 0, a
ld d, 0
ld iy, 86400
ld hl, (ix - 3)
ld e, (ix - 4)
ld a, 1
call __lcmpu
jr c, BB0_5
call __lsub
ld (ix - 3), hl
ld (ix - 4), e
ld iy, (_gmtime.tm2+15)
inc iy
ld (_gmtime.tm2+15), iy
jr BB0_1
BB0_5:
lea bc, iy
ld a, d
call __ldivu
ld (_gmtime.tm2+21), hl
ld hl, (_gmtime.tm2+15)
push hl
call _istmleap
pop hl
bit 0, a
jr z, BB0_7
ld a, 29
ld (_gmtime.dpm+1), a
BB0_7:
ld bc, (_gmtime.tm2+12)
ld d, 0
ld a, d
ld hl, _gmtime.dpm
BB0_8:
ld iy, 0
ld (ix - 7), bc
add hl, bc
push af
ld a, (hl)
ld iyl, a
pop af
ld e, iyh
lea hl, iy
ld bc, 86400
ld d, a
call __lmulu
push hl
pop bc
ld a, e
ld hl, (ix - 3)
ld e, (ix - 4)
call __lcmpu
jr c, BB0_10
ld e, 0
ld hl, (ix - 7)
push hl
pop bc
inc bc
ld (ix - 10), bc
inc hl
ld (_gmtime.tm2+12), hl
lea hl, iy
ld bc, -86400
ld a, -1
call __lmulu
ld bc, (ix - 3)
ld a, (ix - 4)
call __ladd
ld (ix - 3), hl
ld (ix - 4), e
ld bc, (ix - 10)
ld hl, _gmtime.dpm
ld a, d
jr BB0_8
BB0_10:
ld a, 28
ld (_gmtime.dpm+1), a
ld iy, (_gmtime.tm2+9)
inc iy
ld bc, (ix - 3)
ld a, (ix - 4)
BB0_11:
ld hl, 86399
ld e, d
call __lcmpu
jr nc, BB0_13
push bc
pop hl
ld e, a
ld bc, -86400
ld a, -1
call __ladd
push hl
pop bc
ld a, e
ld (_gmtime.tm2+9), iy
inc iy
jr BB0_11
BB0_13:
ld iy, (_gmtime.tm2+6)
BB0_14:
inc iy
ld hl, 3599
ld e, d
call __lcmpu
jr nc, BB0_16
push bc
pop hl
ld e, a
ld bc, -3600
ld a, -1
call __ladd
push hl
pop bc
ld a, e
ld (_gmtime.tm2+6), iy
jr BB0_14
BB0_16:
ld iy, (_gmtime.tm2+3)
BB0_17:
inc iy
ld hl, 59
ld e, d
call __lcmpu
jr nc, BB0_19
push bc
pop hl
ld e, a
ld bc, -60
ld a, b
call __ladd
push hl
pop bc
ld a, e
ld (_gmtime.tm2+3), iy
jr BB0_17
BB0_19:
ld (_gmtime.tm2), bc
ld hl, _gmtime.tm2
ld sp, ix
pop ix
ret
section .text,"ax",@progbits

section .text,"ax",@progbits
private _istmleap
_istmleap:
call __frameset0
ld hl, (ix + 6)
ld de, 1900
add hl, de
ld (ix + 6), hl
pop ix
jp ___isleap
section .text,"ax",@progbits

section .data,"aw",@progbits
private _gmtime.dpm
_gmtime.dpm:
db ""

section .bss,"aw",@nobits
private _gmtime.tm2
_gmtime.tm2:
rb 27

ident "clang version 15.0.0 (https://github.com/jacobly0/llvm-project 6c61664110f888c0285ae4c48b150c9a7a4361bb)"
extern __ldivu
extern __Unwind_SjLj_Register
extern __Unwind_SjLj_Unregister
extern __frameset
extern __sremu
extern __lmulu
extern __lsub
extern __lcmpu
extern __frameset0
extern __ladd
extern ___isleap
24 changes: 24 additions & 0 deletions lib/libc/localtime.c.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
section .text,"ax",@progbits
assume adl = 1
section .text,"ax",@progbits
public _localtime
_localtime:
ld hl, -4
call __frameset
ld iy, (ix + 6)
ld hl, (iy)
ld a, (iy + 3)
ld (ix - 4), hl
ld (ix - 1), a
pea ix - 4
call _gmtime
ld sp, ix
pop ix
ret
section .text,"ax",@progbits

ident "clang version 15.0.0 (https://github.com/jacobly0/llvm-project 6c61664110f888c0285ae4c48b150c9a7a4361bb)"
extern __Unwind_SjLj_Register
extern __Unwind_SjLj_Unregister
extern __frameset
extern _gmtime
Loading

0 comments on commit ba44b62

Please sign in to comment.