From a6a91349bcf7225995a56fb3e84865277f1abebd Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Tue, 2 Dec 2025 21:37:14 -0800 Subject: [PATCH 01/10] make time zone work --- include/time.h | 9 ++++++--- libsrc/common/localtime.s | 36 ++++++++++++++++++++++++++---------- libsrc/common/tzset_time.s | 16 ++++++++++++++++ libsrc/rp6502/ria_tzset.c | 9 --------- libsrc/rp6502/tzset_time.s | 29 +++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 libsrc/common/tzset_time.s delete mode 100644 libsrc/rp6502/ria_tzset.c create mode 100644 libsrc/rp6502/tzset_time.s diff --git a/include/time.h b/include/time.h index 5eb6f144a..3fab28454 100644 --- a/include/time.h +++ b/include/time.h @@ -128,12 +128,15 @@ extern struct _timezone { char dstname[5]; /* Name when daylight true, e.g. CEST */ } _tz; +/* Set _tz for a specific time, if supported by target */ +void __fastcall__ tzset_time (time_t* t); + #define CLK_TCK CLOCKS_PER_SEC /* 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); +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); #endif diff --git a/libsrc/common/localtime.s b/libsrc/common/localtime.s index 279442c9d..bc64a19cd 100644 --- a/libsrc/common/localtime.s +++ b/libsrc/common/localtime.s @@ -5,16 +5,27 @@ ; .export _localtime - .import __time_t_to_tm, __tz + .import __time_t_to_tm, __tz, _tzset_time .import ldeaxi, tosaddeax, pusheax - .importzp sreg + .importzp sreg, ptr1 _localtime: - cpx #$00 ; Check for null pointer - bne :+ - cmp #$00 - beq no_pointer -: jsr ldeaxi ; Load value +.if .cap(CPU_HAS_PUSHXY) + pha + phx + jsr _tzset_time + plx + pla +.else + pha + txa + pha + jsr _tzset_time + pla + tax + pla +.endif + jsr ldeaxi ; Load value jsr pusheax ; Push it lda __tz+1+3 sta sreg+1 @@ -23,7 +34,12 @@ _localtime: ldx __tz+1+1 lda __tz+1 jsr tosaddeax ; Add _tz.timezone - jmp __time_t_to_tm ; Convert to struct tm - -no_pointer: + jsr __time_t_to_tm ; Convert to struct tm + sta ptr1 ; Save returned tm pointer + stx ptr1+1 + ldy #16 + lda __tz+0 ; Load _tz.daylight + sta (ptr1),y ; Store to tm.tm_isdst + lda ptr1 ; Restore returned tm pointer + ldx ptr1+1 rts ; A/X already set diff --git a/libsrc/common/tzset_time.s b/libsrc/common/tzset_time.s new file mode 100644 index 000000000..5c0160404 --- /dev/null +++ b/libsrc/common/tzset_time.s @@ -0,0 +1,16 @@ +; tzset_time.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://cc65.github.io +; +; See "LICENSE" file for legal information. +; +; void __fastcall__ tzset_time (time_t* time); +; + + .export _tzset_time + +_tzset_time: + rts diff --git a/libsrc/rp6502/ria_tzset.c b/libsrc/rp6502/ria_tzset.c deleted file mode 100644 index 3f39e44f2..000000000 --- a/libsrc/rp6502/ria_tzset.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int clock_gettimezone (time_t time, clockid_t clock_id, struct _timezone* tz); - -void ria_tzset (unsigned long time) -{ - clock_gettimezone (time, CLOCK_REALTIME, &_tz); -} diff --git a/libsrc/rp6502/tzset_time.s b/libsrc/rp6502/tzset_time.s new file mode 100644 index 000000000..60c1177d7 --- /dev/null +++ b/libsrc/rp6502/tzset_time.s @@ -0,0 +1,29 @@ +; tzset_time.s +; +; This file is part of +; cc65 - a freeware C compiler for 6502 based systems +; +; https://cc65.github.io +; +; See "LICENSE" file for legal information. +; +; void __fastcall__ tzset_time (time_t* time); +; + + .export _tzset_time + .import _clock_gettimezone, __tz + .import pushax, ldax0sp, ldeaxi, pusheax, pusha, incsp2 + .include "time.inc" + + +_tzset_time: + jsr pushax + jsr ldax0sp + jsr ldeaxi + jsr pusheax + lda #CLOCK_REALTIME + jsr pusha + lda #<(__tz) + ldx #>(__tz) + jsr _clock_gettimezone + jmp incsp2 From dce4ed65d9e3ba7a9f83420204469fc64e7765b5 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:08:53 -0800 Subject: [PATCH 02/10] remove test for non-standard behavior --- test/val/lib_common_gmtime_localtime.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/val/lib_common_gmtime_localtime.c b/test/val/lib_common_gmtime_localtime.c index f0d9a8332..1e7f9a7b1 100644 --- a/test/val/lib_common_gmtime_localtime.c +++ b/test/val/lib_common_gmtime_localtime.c @@ -70,12 +70,6 @@ int main (void) fails++; } - tm = localtime(NULL); - if (tm != NULL) { - printf("localtime should return NULL with a NULL parameter\n"); - fails++; - } - /* Verify conversion both ways */ for (i = 0; ; i++) { time_t t = data[i].t; @@ -86,7 +80,7 @@ int main (void) printf("0x%lx: gmtime: unexpected result: expected %s, got %s\n", t, data[i].gmt, str); fails++; } - + _tz.timezone = 0; tm = localtime(&t); str = asctime(tm); From 71f2ffbffcb73a0e2b79aee4f101c6d1ef77ce7d Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Wed, 3 Dec 2025 00:45:25 -0800 Subject: [PATCH 03/10] remove time zone hack --- include/rp6502.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/rp6502.h b/include/rp6502.h index 2c0e78b87..c478c5dd3 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -171,10 +171,6 @@ int __fastcall__ f_setlabel (const char* name); int __fastcall__ f_getlabel (const char* path, char* label); int __fastcall__ f_getfree (const char* name, unsigned long* free, unsigned long* total); -/* Time zone hack */ - -void ria_tzset (unsigned long time); - /* XREG location helpers */ #define xreg_ria_keyboard(...) xreg(0, 0, 0, __VA_ARGS__) From dbdca1344426a42aa94a3857cc3e5d8d18f44abd Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Fri, 5 Dec 2025 15:38:46 -0800 Subject: [PATCH 04/10] optimize and restore null test --- libsrc/common/localtime.s | 29 ++++++++++------------------- libsrc/rp6502/tzset_time.s | 5 +---- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/libsrc/common/localtime.s b/libsrc/common/localtime.s index bc64a19cd..aecea5996 100644 --- a/libsrc/common/localtime.s +++ b/libsrc/common/localtime.s @@ -10,23 +10,13 @@ .importzp sreg, ptr1 _localtime: -.if .cap(CPU_HAS_PUSHXY) - pha - phx - jsr _tzset_time - plx - pla -.else - pha - txa - pha - jsr _tzset_time - pla - tax - pla -.endif - jsr ldeaxi ; Load value + cpx #$00 ; Check for null pointer + bne :+ + cmp #$00 + beq no_pointer +: jsr ldeaxi ; Load value jsr pusheax ; Push it + jsr _tzset_time lda __tz+1+3 sta sreg+1 lda __tz+1+2 @@ -35,11 +25,12 @@ _localtime: lda __tz+1 jsr tosaddeax ; Add _tz.timezone jsr __time_t_to_tm ; Convert to struct tm - sta ptr1 ; Save returned tm pointer + sta ptr1 ; Returned tm pointer stx ptr1+1 ldy #16 lda __tz+0 ; Load _tz.daylight sta (ptr1),y ; Store to tm.tm_isdst - lda ptr1 ; Restore returned tm pointer - ldx ptr1+1 + lda ptr1 + +no_pointer: rts ; A/X already set diff --git a/libsrc/rp6502/tzset_time.s b/libsrc/rp6502/tzset_time.s index 60c1177d7..5bf1768a1 100644 --- a/libsrc/rp6502/tzset_time.s +++ b/libsrc/rp6502/tzset_time.s @@ -17,13 +17,10 @@ _tzset_time: - jsr pushax - jsr ldax0sp jsr ldeaxi jsr pusheax lda #CLOCK_REALTIME jsr pusha lda #<(__tz) ldx #>(__tz) - jsr _clock_gettimezone - jmp incsp2 + jmp _clock_gettimezone From 18f084eafb47f3263319b19223abafeac77ff5f4 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:30:14 -0800 Subject: [PATCH 05/10] restore test --- test/val/lib_common_gmtime_localtime.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/val/lib_common_gmtime_localtime.c b/test/val/lib_common_gmtime_localtime.c index 1e7f9a7b1..f0d9a8332 100644 --- a/test/val/lib_common_gmtime_localtime.c +++ b/test/val/lib_common_gmtime_localtime.c @@ -70,6 +70,12 @@ int main (void) fails++; } + tm = localtime(NULL); + if (tm != NULL) { + printf("localtime should return NULL with a NULL parameter\n"); + fails++; + } + /* Verify conversion both ways */ for (i = 0; ; i++) { time_t t = data[i].t; @@ -80,7 +86,7 @@ int main (void) printf("0x%lx: gmtime: unexpected result: expected %s, got %s\n", t, data[i].gmt, str); fails++; } - + _tz.timezone = 0; tm = localtime(&t); str = asctime(tm); From 328f7e6a43fa9dde43ddbc21f0b27ea673c6a813 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 6 Dec 2025 11:38:27 -0800 Subject: [PATCH 06/10] yes! --- include/rp6502.h | 3 ++- include/time.h | 8 +++----- libsrc/common/localtime.s | 13 +++---------- libsrc/rp6502/gettimezone.c | 17 ----------------- libsrc/rp6502/localtime.s | 12 ++++++++++++ libsrc/rp6502/localtime_.c | 31 +++++++++++++++++++++++++++++++ libsrc/rp6502/tzset_time.s | 26 -------------------------- 7 files changed, 51 insertions(+), 59 deletions(-) delete mode 100644 libsrc/rp6502/gettimezone.c create mode 100644 libsrc/rp6502/localtime.s create mode 100644 libsrc/rp6502/localtime_.c delete mode 100644 libsrc/rp6502/tzset_time.s diff --git a/include/rp6502.h b/include/rp6502.h index c478c5dd3..434f2d130 100644 --- a/include/rp6502.h +++ b/include/rp6502.h @@ -96,11 +96,12 @@ long __fastcall__ ria_call_long (unsigned char op); #define RIA_OP_LRAND 0x04 #define RIA_OP_STDIN_OPT 0x05 #define RIA_OP_ERRNO_OPT 0x06 +#define RIA_OP_TZSET 0x0D +#define RIA_OP_TZQUERY 0x0E #define RIA_OP_CLOCK 0x0F #define RIA_OP_CLOCK_GETRES 0x10 #define RIA_OP_CLOCK_GETTIME 0x11 #define RIA_OP_CLOCK_SETTIME 0x12 -#define RIA_OP_CLOCK_GETTIMEZONE 0x13 #define RIA_OP_OPEN 0x14 #define RIA_OP_CLOSE 0x15 #define RIA_OP_READ_XSTACK 0x16 diff --git a/include/time.h b/include/time.h index 3fab28454..476323a70 100644 --- a/include/time.h +++ b/include/time.h @@ -108,6 +108,7 @@ struct tm* __fastcall__ localtime (const time_t* timep); time_t __fastcall__ mktime (struct tm* timep); size_t __fastcall__ strftime (char* buf, size_t bufsize, const char* format, const struct tm* tm); time_t __fastcall__ time (time_t* t); +void tzset (void); #if __CC65_STD__ >= __CC65_STD_CC65__ @@ -124,13 +125,10 @@ struct timespec { extern struct _timezone { char daylight; /* True if daylight savings time active */ long timezone; /* Number of seconds behind UTC */ - char tzname[5]; /* Name of timezone, e.g. CET */ - char dstname[5]; /* Name when daylight true, e.g. CEST */ + char tzname[6]; /* Name of timezone, e.g. CET */ + char dstname[6]; /* Name when daylight true, e.g. CEST */ } _tz; -/* Set _tz for a specific time, if supported by target */ -void __fastcall__ tzset_time (time_t* t); - #define CLK_TCK CLOCKS_PER_SEC /* POSIX function prototypes */ diff --git a/libsrc/common/localtime.s b/libsrc/common/localtime.s index aecea5996..279442c9d 100644 --- a/libsrc/common/localtime.s +++ b/libsrc/common/localtime.s @@ -5,9 +5,9 @@ ; .export _localtime - .import __time_t_to_tm, __tz, _tzset_time + .import __time_t_to_tm, __tz .import ldeaxi, tosaddeax, pusheax - .importzp sreg, ptr1 + .importzp sreg _localtime: cpx #$00 ; Check for null pointer @@ -16,7 +16,6 @@ _localtime: beq no_pointer : jsr ldeaxi ; Load value jsr pusheax ; Push it - jsr _tzset_time lda __tz+1+3 sta sreg+1 lda __tz+1+2 @@ -24,13 +23,7 @@ _localtime: ldx __tz+1+1 lda __tz+1 jsr tosaddeax ; Add _tz.timezone - jsr __time_t_to_tm ; Convert to struct tm - sta ptr1 ; Returned tm pointer - stx ptr1+1 - ldy #16 - lda __tz+0 ; Load _tz.daylight - sta (ptr1),y ; Store to tm.tm_isdst - lda ptr1 + jmp __time_t_to_tm ; Convert to struct tm no_pointer: rts ; A/X already set diff --git a/libsrc/rp6502/gettimezone.c b/libsrc/rp6502/gettimezone.c deleted file mode 100644 index 4c4584c07..000000000 --- a/libsrc/rp6502/gettimezone.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -int clock_gettimezone (time_t time, clockid_t clock_id, struct _timezone* tz) -{ - int ax; - ria_set_ax (clock_id); - ria_push_long (time); - ax = ria_call_int (RIA_OP_CLOCK_GETTIMEZONE); - if (ax >= 0) { - char i; - for (i = 0; i < sizeof (struct _timezone); i++) { - ((char*)tz)[i] = ria_pop_char (); - } - } - return ax; -} diff --git a/libsrc/rp6502/localtime.s b/libsrc/rp6502/localtime.s new file mode 100644 index 000000000..89984770d --- /dev/null +++ b/libsrc/rp6502/localtime.s @@ -0,0 +1,12 @@ +; +; struct tm* __fastcall__ localtime (const time_t* timep); +; + + .export _localtime + + .import __localtime + + +;-------------------------------------------------------------------------- + +_localtime = __localtime diff --git a/libsrc/rp6502/localtime_.c b/libsrc/rp6502/localtime_.c new file mode 100644 index 000000000..6455c69f7 --- /dev/null +++ b/libsrc/rp6502/localtime_.c @@ -0,0 +1,31 @@ +#include +#include +#include + +static bool tzset_set = false; + +struct tm* __fastcall__ _time_t_to_tm (const time_t t); + +struct tm* __fastcall__ _localtime (const time_t* timep) +{ + long time = *timep; + struct tm* tm; + ria_set_axsreg (*timep); + time += ria_call_long (RIA_OP_TZQUERY); + tm = _time_t_to_tm (time); + tm->tm_isdst = ria_pop_char (); + if (!tzset_set) { tzset (); } + return tm; +} + +void tzset (void) +{ + int ax = ria_call_int (RIA_OP_TZSET); + if (ax >= 0) { + char i; + for (i = 0; i < sizeof (struct _timezone); i++) { + ((char*)&_tz)[i] = ria_pop_char (); + } + tzset_set = true; + } +} diff --git a/libsrc/rp6502/tzset_time.s b/libsrc/rp6502/tzset_time.s deleted file mode 100644 index 5bf1768a1..000000000 --- a/libsrc/rp6502/tzset_time.s +++ /dev/null @@ -1,26 +0,0 @@ -; tzset_time.s -; -; This file is part of -; cc65 - a freeware C compiler for 6502 based systems -; -; https://cc65.github.io -; -; See "LICENSE" file for legal information. -; -; void __fastcall__ tzset_time (time_t* time); -; - - .export _tzset_time - .import _clock_gettimezone, __tz - .import pushax, ldax0sp, ldeaxi, pusheax, pusha, incsp2 - .include "time.inc" - - -_tzset_time: - jsr ldeaxi - jsr pusheax - lda #CLOCK_REALTIME - jsr pusha - lda #<(__tz) - ldx #>(__tz) - jmp _clock_gettimezone From 6ac362af870dd6ab2852b42ec5cc933b4560ed43 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 6 Dec 2025 11:41:52 -0800 Subject: [PATCH 07/10] indeed! --- libsrc/common/tzset_time.s | 16 ---------------- libsrc/rp6502/{localtime_.c => _localtime.c} | 0 2 files changed, 16 deletions(-) delete mode 100644 libsrc/common/tzset_time.s rename libsrc/rp6502/{localtime_.c => _localtime.c} (100%) diff --git a/libsrc/common/tzset_time.s b/libsrc/common/tzset_time.s deleted file mode 100644 index 5c0160404..000000000 --- a/libsrc/common/tzset_time.s +++ /dev/null @@ -1,16 +0,0 @@ -; tzset_time.s -; -; This file is part of -; cc65 - a freeware C compiler for 6502 based systems -; -; https://cc65.github.io -; -; See "LICENSE" file for legal information. -; -; void __fastcall__ tzset_time (time_t* time); -; - - .export _tzset_time - -_tzset_time: - rts diff --git a/libsrc/rp6502/localtime_.c b/libsrc/rp6502/_localtime.c similarity index 100% rename from libsrc/rp6502/localtime_.c rename to libsrc/rp6502/_localtime.c From 48b936b767a0a991ac3f1f9f27607906d50d72ac Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 6 Dec 2025 12:13:36 -0800 Subject: [PATCH 08/10] nah it's 4 --- include/time.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/time.h b/include/time.h index 476323a70..210e49fb1 100644 --- a/include/time.h +++ b/include/time.h @@ -125,8 +125,8 @@ struct timespec { extern struct _timezone { char daylight; /* True if daylight savings time active */ long timezone; /* Number of seconds behind UTC */ - char tzname[6]; /* Name of timezone, e.g. CET */ - char dstname[6]; /* Name when daylight true, e.g. CEST */ + char tzname[5]; /* Name of timezone, e.g. CET */ + char dstname[5]; /* Name when daylight true, e.g. CEST */ } _tz; #define CLK_TCK CLOCKS_PER_SEC From 8ff7b0087c73a8f201fcc2d2d3915e9c553b97c5 Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sat, 6 Dec 2025 12:56:20 -0800 Subject: [PATCH 09/10] doh --- libsrc/rp6502/_localtime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsrc/rp6502/_localtime.c b/libsrc/rp6502/_localtime.c index 6455c69f7..2b3cb013f 100644 --- a/libsrc/rp6502/_localtime.c +++ b/libsrc/rp6502/_localtime.c @@ -8,7 +8,7 @@ struct tm* __fastcall__ _time_t_to_tm (const time_t t); struct tm* __fastcall__ _localtime (const time_t* timep) { - long time = *timep; + time_t time = *timep; struct tm* tm; ria_set_axsreg (*timep); time += ria_call_long (RIA_OP_TZQUERY); From dde04808aa1298a457b8c2e38c974ff44c8b2a0e Mon Sep 17 00:00:00 2001 From: rumbledethumps <16963588+rumbledethumps@users.noreply.github.com> Date: Sun, 7 Dec 2025 11:42:02 -0800 Subject: [PATCH 10/10] the bytes, they need saving --- libsrc/rp6502/_localtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/rp6502/_localtime.c b/libsrc/rp6502/_localtime.c index 2b3cb013f..8c76e3a26 100644 --- a/libsrc/rp6502/_localtime.c +++ b/libsrc/rp6502/_localtime.c @@ -8,9 +8,9 @@ struct tm* __fastcall__ _time_t_to_tm (const time_t t); struct tm* __fastcall__ _localtime (const time_t* timep) { - time_t time = *timep; struct tm* tm; - ria_set_axsreg (*timep); + time_t time = *timep; + ria_set_axsreg (time); time += ria_call_long (RIA_OP_TZQUERY); tm = _time_t_to_tm (time); tm->tm_isdst = ria_pop_char ();