From 842c151edd04385901220c5506ecf8c7f9060c26 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Wed, 15 Aug 2018 15:59:11 +0200
Subject: [PATCH] Replaced _systime with clock_gettime.
We want to add the capability to not only get the time but also set the time, but there's no "setter" for the "getter" time().
The first ones that come into mind are gettimeofday() and settimeofday(). However, they take a struct timezone argument that doesn't make sense - even the man pages says "The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL." And POSIX says "Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function."
The ...timeofday() functions work with microseconds while the clock_...time() functions work with nanoseconds. Given that we expect our targets to support only 1/10 of seconds the microseconds look preferable at first sight. However, already microseconds require the cc65 data type 'long' so it's not such a relevant difference to nanoseconds. Additionally clock_getres() seems useful.
In order to avoid code duplication clock_gettime() takes over the role of the actual time getter from _systime(). So time() now calls clock_gettime() instead of _systime().
For some reason beyond my understanding _systime() was mentioned in time.h. _systime() worked exactly like e.g. _sysremove() and those _sys...() functions are all considered internal. The only reason I could see would be a performance gain of bypassing the time() wrapper. However, all known _systime() implementations internally called mktime(). And mktime() is implemented in C using an iterative algorithm so I really can't see what would be left to gain here. From that perspective I decided to just remove _systime().
---
asminc/time.inc | 13 ++-
doc/funcref.sgml | 2 +-
include/time.h | 24 +++--
libsrc/apple2/gettime.s | 92 +++++++++++++++++++
libsrc/apple2/systime.s | 63 -------------
libsrc/atari/systime.s | 28 ------
libsrc/atmos/systime.s | 28 ------
libsrc/c128/{systime.s => gettime.s} | 51 +++++++---
libsrc/c16/systime.s | 28 ------
libsrc/c64/{systime.s => gettime.s} | 51 +++++++---
libsrc/cbm510/{systime.s => gettime.s} | 51 +++++-----
libsrc/cbm610/{systime.s => gettime.s} | 50 ++++++----
libsrc/common/time.s | 39 +++++---
.../system/{systime.c => gettime.c} | 11 ++-
libsrc/plus4/systime.s | 28 ------
15 files changed, 292 insertions(+), 267 deletions(-)
create mode 100644 libsrc/apple2/gettime.s
delete mode 100644 libsrc/apple2/systime.s
delete mode 100644 libsrc/atari/systime.s
delete mode 100644 libsrc/atmos/systime.s
rename libsrc/c128/{systime.s => gettime.s} (66%)
delete mode 100644 libsrc/c16/systime.s
rename libsrc/c64/{systime.s => gettime.s} (66%)
rename libsrc/cbm510/{systime.s => gettime.s} (66%)
rename libsrc/cbm610/{systime.s => gettime.s} (66%)
rename libsrc/geos-common/system/{systime.c => gettime.c} (81%)
delete mode 100644 libsrc/plus4/systime.s
diff --git a/asminc/time.inc b/asminc/time.inc
index 16858471d..5783232c7 100644
--- a/asminc/time.inc
+++ b/asminc/time.inc
@@ -49,10 +49,21 @@
.endstruct
+;------------------------------------------------------------------------------
+; Struct timespec - must match the struct defined in time.h
+
+.struct timespec
+ tv_sec .dword
+ tv_nsec .dword
+.endstruct
+
+
;------------------------------------------------------------------------------
; Exported functions
-.global __systime
+.global _clock_getres
+.global _clock_gettime
+.global _clock_settime
.global _mktime
diff --git a/doc/funcref.sgml b/doc/funcref.sgml
index edb510e37..247689b8a 100644
--- a/doc/funcref.sgml
+++ b/doc/funcref.sgml
@@ -7375,7 +7375,7 @@ be used in presence of a prototype.
- The function is only available as fastcall function, so it may
only be used in presence of a prototype.
diff --git a/include/time.h b/include/time.h
index 22e24a56e..4ee658da9 100644
--- a/include/time.h
+++ b/include/time.h
@@ -52,9 +52,10 @@ typedef unsigned size_t;
typedef unsigned long time_t;
typedef unsigned long clock_t;
+typedef unsigned char clockid_t;
/* Structure for broken down time */
-struct tm {
+struct tm {
int tm_sec;
int tm_min;
int tm_hour;
@@ -66,6 +67,12 @@ struct tm {
int tm_isdst;
};
+/* Structure for seconds and nanoseconds */
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+
/* Timezone representation, default is UTC */
extern struct _timezone {
char daylight; /* True if daylight savings time active */
@@ -116,16 +123,10 @@ extern clock_t _clk_tck (void);
# define CLK_TCK _clk_tck()
# define CLOCKS_PER_SEC _clk_tck()
#endif
+#define CLOCK_REALTIME 0
-time_t _systime (void);
-/* Similar to time(), but:
-** - Is not ISO C
-** - Does not take the additional pointer
-** - Does not set errno when returning -1
-*/
-
/* ISO C function prototypes */
char* __fastcall__ asctime (const struct tm* timep);
clock_t clock (void);
@@ -138,6 +139,13 @@ time_t __fastcall__ time (time_t* t);
+/* POSIX function prototypes */
+int __fastcall__ clock_getres (clockid_t clock_id, struct timespec *res);
+int __fastcall__ clock_gettime (clockid_t clock_id, struct timespec *tp);
+int __fastcall__ clock_settime (clockid_t clock_id, const struct timespec *tp);
+
+
+
/* End of time.h */
#endif
diff --git a/libsrc/apple2/gettime.s b/libsrc/apple2/gettime.s
new file mode 100644
index 000000000..6bb541548
--- /dev/null
+++ b/libsrc/apple2/gettime.s
@@ -0,0 +1,92 @@
+;
+; Oliver Schmidt, 14.08.2018
+;
+; int clock_gettime (clockid_t clk_id, struct timespec *tp);
+;
+
+ .import pushax, steaxspidx, incsp1, incsp3, return0
+
+ .include "time.inc"
+ .include "zeropage.inc"
+ .include "errno.inc"
+ .include "mli.inc"
+
+_clock_gettime:
+ jsr pushax
+
+ ; Clear tv_nsec (+ tv_sec)
+ sta ptr1
+ stx ptr1+1
+ lda #$00
+ ldy #.sizeof(timespec)-1
+: sta (ptr1),y
+ dey
+ bpl :-
+
+ ; Update date + time
+ lda #GET_TIME_CALL
+ ldx #GET_TIME_COUNT
+ jsr callmli
+ bcs oserr
+
+ ; Get date
+ lda DATELO+1
+ lsr
+ php ; Save month msb
+ cmp #70 ; Year < 70?
+ bcs :+ ; No, leave alone
+ adc #100 ; Move 19xx to 20xx
+: sta TM + tm::tm_year
+ lda DATELO
+ tax ; Save day
+ plp ; Restore month msb
+ ror
+ lsr
+ lsr
+ lsr
+ lsr
+ beq erange ; [1..12] allows for validity check
+ tay
+ dey ; Move [1..12] to [0..11]
+ sty TM + tm::tm_mon
+ txa ; Restore day
+ and #%00011111
+ sta TM + tm::tm_mday
+
+ ; Get time
+ lda TIMELO+1
+ sta TM + tm::tm_hour
+ lda TIMELO
+ sta TM + tm::tm_min
+
+ ; Make time_t
+ lda #TM
+ jsr _mktime
+
+ ; Store tv_sec
+ ldy #timespec::tv_sec
+ jsr steaxspidx
+
+ ; Return success
+ jsr incsp1
+ jmp return0
+
+ ; Load errno code
+erange: lda #ERANGE
+
+ ; Cleanup stack
+ jsr incsp3 ; Preserves A
+
+ ; Set __errno
+ jmp __directerrno
+
+ ; Cleanup stack
+oserr: jsr incsp3 ; Preserves A
+
+ ; Set __oserror
+ jmp __mappederrno
+
+ .bss
+
+TM: .tag tm
diff --git a/libsrc/apple2/systime.s b/libsrc/apple2/systime.s
deleted file mode 100644
index 9bf4fe904..000000000
--- a/libsrc/apple2/systime.s
+++ /dev/null
@@ -1,63 +0,0 @@
-;
-; Oliver Schmidt, 22.08.2006
-;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
-;
-
- .include "time.inc"
- .include "zeropage.inc"
- .include "mli.inc"
-
-__systime:
- ; Update time
- lda #GET_TIME_CALL
- ldx #GET_TIME_COUNT
- jsr callmli
- bcs err
-
- lda DATELO+1
- lsr
- php ; Save month msb
- cmp #70 ; Year < 70?
- bcs :+ ; No, leave alone
- adc #100 ; Move 19xx to 20xx
-: sta TM + tm::tm_year
- lda DATELO
- tax ; Save day
- plp ; Restore month msb
- ror
- lsr
- lsr
- lsr
- lsr
- beq err ; [1..12] allows for validity check
- tay
- dey ; Move [1..12] to [0..11]
- sty TM + tm::tm_mon
- txa ; Restore day
- and #%00011111
- sta TM + tm::tm_mday
-
- lda TIMELO+1
- sta TM + tm::tm_hour
- lda TIMELO
- sta TM + tm::tm_min
-
- lda #TM
- jmp _mktime
-
-err: lda #$FF
- tax
- sta sreg
- sta sreg+1
- rts ; Return -1
-
- .bss
-
-TM: .tag tm
diff --git a/libsrc/atari/systime.s b/libsrc/atari/systime.s
deleted file mode 100644
index 273e394a4..000000000
--- a/libsrc/atari/systime.s
+++ /dev/null
@@ -1,28 +0,0 @@
-;
-; Ullrich von Bassewitz, 12.11.2002
-;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
-;
-
- .export __systime
-
- .importzp sreg
-
-.code
-
-.proc __systime
-
- lda #$FF
- tax
- sta sreg
- sta sreg+1
- rts ; Return -1
-
-.endproc
-
-
diff --git a/libsrc/atmos/systime.s b/libsrc/atmos/systime.s
deleted file mode 100644
index 273e394a4..000000000
--- a/libsrc/atmos/systime.s
+++ /dev/null
@@ -1,28 +0,0 @@
-;
-; Ullrich von Bassewitz, 12.11.2002
-;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
-;
-
- .export __systime
-
- .importzp sreg
-
-.code
-
-.proc __systime
-
- lda #$FF
- tax
- sta sreg
- sta sreg+1
- rts ; Return -1
-
-.endproc
-
-
diff --git a/libsrc/c128/systime.s b/libsrc/c128/gettime.s
similarity index 66%
rename from libsrc/c128/systime.s
rename to libsrc/c128/gettime.s
index b2a7f8721..b59789117 100644
--- a/libsrc/c128/systime.s
+++ b/libsrc/c128/gettime.s
@@ -1,27 +1,27 @@
;
; Stefan Haubenthal, 27.7.2009
+; Oliver Schmidt, 14.8.2018
;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
+; int clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "c128.inc"
.include "get_tv.inc"
- .constructor initsystime
- .importzp tmp1, tmp2
+ .constructor inittime
+ .importzp sreg, tmp1, tmp2
+ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0
.import _get_tv
;----------------------------------------------------------------------------
.code
-.proc __systime
+.proc _clock_gettime
+
+ jsr pushax
+ jsr pushax
lda CIA1_TODHR
bpl AM
@@ -38,13 +38,38 @@ AM: jsr BCD2dec
lda CIA1_TODSEC
jsr BCD2dec
sta TM + tm::tm_sec
- lda CIA1_TOD10 ; Dummy read to unfreeze
lda #TM
- jmp _mktime
+ jsr _mktime
+
+ ldy #timespec::tv_sec
+ jsr steaxspidx ; Pops address pushed by 2. pushax
+
+ lda #<(100 * 1000 * 1000 / $10000)
+ ldx #>(100 * 1000 * 1000 / $10000)
+ sta sreg
+ stx sreg+1
+ lda #<(100 * 1000 * 1000)
+ ldx #>(100 * 1000 * 1000)
+ jsr pusheax
+ lda CIA1_TOD10
+ ldx #>$0000
+ jsr tosmul0ax
+
+ ldy #timespec::tv_nsec
+ jsr steaxspidx ; Pops address pushed by 1. pushax
+
+ jsr incsp1
+ jmp return0
+.endproc
+
+;----------------------------------------------------------------------------
; dec = (((BCD>>4)*10) + (BCD&0xf))
-BCD2dec:tax
+
+.proc BCD2dec
+
+ tax
and #%00001111
sta tmp1
txa
@@ -65,7 +90,7 @@ BCD2dec:tax
; and write it again, ignoring a possible change in between.
.segment "ONCE"
-.proc initsystime
+.proc inittime
lda CIA1_TOD10
sta CIA1_TOD10
diff --git a/libsrc/c16/systime.s b/libsrc/c16/systime.s
deleted file mode 100644
index 273e394a4..000000000
--- a/libsrc/c16/systime.s
+++ /dev/null
@@ -1,28 +0,0 @@
-;
-; Ullrich von Bassewitz, 12.11.2002
-;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
-;
-
- .export __systime
-
- .importzp sreg
-
-.code
-
-.proc __systime
-
- lda #$FF
- tax
- sta sreg
- sta sreg+1
- rts ; Return -1
-
-.endproc
-
-
diff --git a/libsrc/c64/systime.s b/libsrc/c64/gettime.s
similarity index 66%
rename from libsrc/c64/systime.s
rename to libsrc/c64/gettime.s
index c28ace32e..61c5115ae 100644
--- a/libsrc/c64/systime.s
+++ b/libsrc/c64/gettime.s
@@ -1,27 +1,27 @@
;
; Stefan Haubenthal, 27.7.2009
+; Oliver Schmidt, 14.8.2018
;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
+; int clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "c64.inc"
.include "get_tv.inc"
- .constructor initsystime
- .importzp tmp1, tmp2
+ .constructor inittime
+ .importzp sreg, tmp1, tmp2
+ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0
.import _get_tv, _get_ostype
;----------------------------------------------------------------------------
.code
-.proc __systime
+.proc _clock_gettime
+
+ jsr pushax
+ jsr pushax
lda CIA1_TODHR
bpl AM
@@ -38,13 +38,38 @@ AM: jsr BCD2dec
lda CIA1_TODSEC
jsr BCD2dec
sta TM + tm::tm_sec
- lda CIA1_TOD10 ; Dummy read to unfreeze
lda #TM
- jmp _mktime
+ jsr _mktime
+
+ ldy #timespec::tv_sec
+ jsr steaxspidx ; Pops address pushed by 2. pushax
+
+ lda #<(100 * 1000 * 1000 / $10000)
+ ldx #>(100 * 1000 * 1000 / $10000)
+ sta sreg
+ stx sreg+1
+ lda #<(100 * 1000 * 1000)
+ ldx #>(100 * 1000 * 1000)
+ jsr pusheax
+ lda CIA1_TOD10
+ ldx #>$0000
+ jsr tosmul0ax
+
+ ldy #timespec::tv_nsec
+ jsr steaxspidx ; Pops address pushed by 1. pushax
+
+ jsr incsp1
+ jmp return0
+.endproc
+
+;----------------------------------------------------------------------------
; dec = (((BCD>>4)*10) + (BCD&0xf))
-BCD2dec:tax
+
+.proc BCD2dec
+
+ tax
and #%00001111
sta tmp1
txa
@@ -65,7 +90,7 @@ BCD2dec:tax
; and write it again, ignoring a possible change in between.
.segment "ONCE"
-.proc initsystime
+.proc inittime
lda CIA1_TOD10
sta CIA1_TOD10
diff --git a/libsrc/cbm510/systime.s b/libsrc/cbm510/gettime.s
similarity index 66%
rename from libsrc/cbm510/systime.s
rename to libsrc/cbm510/gettime.s
index daac36d8d..3ad162e3b 100644
--- a/libsrc/cbm510/systime.s
+++ b/libsrc/cbm510/gettime.s
@@ -1,33 +1,28 @@
;
; Stefan Haubenthal, 2009-07-27
; Ullrich von Bassewitz, 2009-09-24
+; Oliver Schmidt, 2018-08-14
;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
+; int clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "cbm510.inc"
.include "extzp.inc"
+ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1
.import sys_bank, restore_bank
- .importzp tmp1, tmp2
+ .importzp sreg, tmp1, tmp2
;----------------------------------------------------------------------------
.code
-.proc __systime
-
-; Switch to the system bank
+.proc _clock_gettime
jsr sys_bank
-
-; Read the clock
+ jsr pushax
+ jsr pushax
ldy #CIA::TODHR
lda (cia2),y
@@ -47,18 +42,33 @@ AM: jsr BCD2dec
lda (cia2),y
jsr BCD2dec
sta TM + tm::tm_sec
+ lda #TM
+ jsr _mktime
+
+ ldy #timespec::tv_sec
+ jsr steaxspidx ; Pops address pushed by 2. pushax
+
+ lda #<(100 * 1000 * 1000 / $10000)
+ ldx #>(100 * 1000 * 1000 / $10000)
+ sta sreg
+ stx sreg+1
+ lda #<(100 * 1000 * 1000)
+ ldx #>(100 * 1000 * 1000)
+ jsr pusheax
ldy #CIA::TOD10
- lda (cia2),y ; Dummy read to unfreeze
-
-; Restore the bank
+ lda (cia2),y
+ ldx #>$0000
+ jsr tosmul0ax
- jsr restore_bank
+ ldy #timespec::tv_nsec
+ jsr steaxspidx ; Pops address pushed by 1. pushax
-; Convert to a time
+ jsr incsp1
- lda #TM
- jmp _mktime
+ lda #0
+ tax
+ jmp restore_bank
.endproc
@@ -95,4 +105,3 @@ TM: .word 0 ; tm_sec
.word 0 ; tm_wday
.word 0 ; tm_yday
.word 0 ; tm_isdst
-
diff --git a/libsrc/cbm610/systime.s b/libsrc/cbm610/gettime.s
similarity index 66%
rename from libsrc/cbm610/systime.s
rename to libsrc/cbm610/gettime.s
index be2bedf6f..30226213d 100644
--- a/libsrc/cbm610/systime.s
+++ b/libsrc/cbm610/gettime.s
@@ -1,33 +1,28 @@
;
; Stefan Haubenthal, 2009-07-27
; Ullrich von Bassewitz, 2009-09-24
+; Oliver Schmidt, 2018-08-14
;
-; time_t _systime (void);
-; /* Similar to time(), but:
-; ** - Is not ISO C
-; ** - Does not take the additional pointer
-; ** - Does not set errno when returning -1
-; */
+; int clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "cbm610.inc"
.include "extzp.inc"
+ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1
.import sys_bank, restore_bank
- .importzp tmp1, tmp2
+ .importzp sreg, tmp1, tmp2
;----------------------------------------------------------------------------
.code
-.proc __systime
-
-; Switch to the system bank
+.proc _clock_gettime
jsr sys_bank
-
-; Read the clock
+ jsr pushax
+ jsr pushax
ldy #CIA::TODHR
lda (cia),y
@@ -47,18 +42,33 @@ AM: jsr BCD2dec
lda (cia),y
jsr BCD2dec
sta TM + tm::tm_sec
+ lda #TM
+ jsr _mktime
+
+ ldy #timespec::tv_sec
+ jsr steaxspidx ; Pops address pushed by 2. pushax
+
+ lda #<(100 * 1000 * 1000 / $10000)
+ ldx #>(100 * 1000 * 1000 / $10000)
+ sta sreg
+ stx sreg+1
+ lda #<(100 * 1000 * 1000)
+ ldx #>(100 * 1000 * 1000)
+ jsr pusheax
ldy #CIA::TOD10
- lda (cia),y ; Dummy read to unfreeze
-
-; Restore the bank
+ lda (cia),y
+ ldx #>$0000
+ jsr tosmul0ax
- jsr restore_bank
+ ldy #timespec::tv_nsec
+ jsr steaxspidx ; Pops address pushed by 1. pushax
-; Convert to a time
+ jsr incsp1
- lda #TM
- jmp _mktime
+ lda #0
+ tax
+ jmp restore_bank
.endproc
diff --git a/libsrc/common/time.s b/libsrc/common/time.s
index 140d47e2c..9b297d4d3 100644
--- a/libsrc/common/time.s
+++ b/libsrc/common/time.s
@@ -6,10 +6,10 @@
.export _time
- .import __systime
- .importzp ptr1, sreg, tmp1
+ .import decsp1
+ .importzp ptr1, sreg, tmp1, tmp2
- .include "errno.inc"
+ .include "time.inc"
.code
@@ -20,8 +20,19 @@
txa
pha ; Save timep
- jsr __systime ; Get the time (machine dependent)
-
+; Get the time (machine dependent)
+
+ jsr decsp1
+ lda #