From 9c7cccf3e5214ebbb3ac031168e349a5f27fb5ae Mon Sep 17 00:00:00 2001 From: Christian Groessler Date: Tue, 25 Sep 2018 02:42:45 +0200 Subject: [PATCH] Atari: clock_gettime() and clock_settime() implementations They are using SpartaDOS-X interfaces and are therefore only working in this environment. --- libsrc/atari/gettime.s | 114 +++++++++++++++++++++++++++++++++++++ libsrc/atari/sdxtime-bss.s | 9 +++ libsrc/atari/settime.s | 101 ++++++++++++++++++++++++++++++-- 3 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 libsrc/atari/gettime.s create mode 100644 libsrc/atari/sdxtime-bss.s diff --git a/libsrc/atari/gettime.s b/libsrc/atari/gettime.s new file mode 100644 index 000000000..093d34843 --- /dev/null +++ b/libsrc/atari/gettime.s @@ -0,0 +1,114 @@ +; +; Oliver Schmidt, 14.08.2018 +; Christian Groessler, 25.09.2018 +; +; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp); +; + + .import pushax, steaxspidx, incsp1, incsp3, return0 + .import __dos_type + .import sdxtry + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "atari.inc" + +_clock_gettime: + jsr pushax + +; clear tp + + sta ptr1 + stx ptr1+1 + lda #$00 + ldy #.sizeof(timespec)-1 +: sta (ptr1),y + dey + bpl :- + +; only supported on SpartaDOS-X >= 4.40 + + lda #SPARTADOS + cmp __dos_type + bne notsupp + lda SDX_VERSION + cmp #$44 + bcc notsupp + +; get date/time from system (SD-X call) +; see settime.s for reasons of using sdxtry + + lda #0 ; init loop count (256) + sta sdxtry + +try_get:lda #SDX_CLK_DEV ; CLK device + sta SDX_DEVICE + ldy #SDX_KD_GETTD ; GETTD function + jsr SDX_KERNEL ; do the call + bcc done + + dec sdxtry + bne try_get + + lda #EBUSY + bne errexit + +; fill timespec + +; date +done: lda SDX_DATE ; mday + sta TM + tm::tm_mday + ldx SDX_DATE+1 ; month + dex + stx TM + tm::tm_mon + lda SDX_DATE+2 ; year + cmp #79 ; 1979: the Atari 800 came out + bcs :+ + adc #100 ; adjust century +: sta TM + tm::tm_year + +; time + lda SDX_TIME + sta TM + tm::tm_hour + lda SDX_TIME+1 + sta TM + tm::tm_min + lda SDX_TIME+2 + sta TM + tm::tm_sec + +; make time_t + + lda #TM + jsr _mktime + +; store tv_sec into output tp struct + + ldy #timespec::tv_sec + jsr steaxspidx + +; cleanup stack + + jsr incsp1 + +; return success + + jmp return0 + +; load errno code + +notsupp:lda #ENOSYS + +; cleanup stack + +errexit:jsr incsp3 ; Preserves A + +; set __errno + + jmp __directerrno + +; ------- + + .bss + +TM: .tag tm diff --git a/libsrc/atari/sdxtime-bss.s b/libsrc/atari/sdxtime-bss.s new file mode 100644 index 000000000..62bb58bba --- /dev/null +++ b/libsrc/atari/sdxtime-bss.s @@ -0,0 +1,9 @@ +; .bss variable used by SpartaDOS-X implementations of +; gettime.s and settime.s + + .export sdxtry + + .bss + +sdxtry: .res 1 ; limit of unsuccessful tries to call GETTD/SETTD + ; (see settime.s) diff --git a/libsrc/atari/settime.s b/libsrc/atari/settime.s index 698aa2a29..7d6fff2c0 100644 --- a/libsrc/atari/settime.s +++ b/libsrc/atari/settime.s @@ -1,8 +1,99 @@ ; -; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; Oliver Schmidt, 15.08.2018 +; Christian Groessler, 25.09.2018 ; - .include "errno.inc" - .export _clock_settime +; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .import __dos_type + .import incsp1, return0 + .import sdxtry + + .include "time.inc" + .include "zeropage.inc" + .include "errno.inc" + .include "atari.inc" + _clock_settime: - lda #ENOSYS - jmp __directerrno + +; cleanup stack + + jsr incsp1 ; preserves AX + +; only supported on SpartaDOS-X >= 4.40 + + ldy #SPARTADOS + cpy __dos_type + bne enosys + ldy SDX_VERSION + cpy #$44 + bcc enosys + +; create tm from tp (tv_sec) input parameter + + .assert timespec::tv_sec = 0, error + jsr _localtime + sta ptr1 + stx ptr1+1 + +; set date + + ldy #tm::tm_mday + lda (ptr1),y ; get day of month + sta SDX_DATE ; set day of month + + ldy #tm::tm_mon + lda (ptr1),y ; get month (0-based) + tax + inx ; move [0..11] to [1..12] + stx SDX_DATE+1 + + ldy #tm::tm_year + lda (ptr1),y ; get year (0 = year 1900) + cmp #100 + bcc :+ + sbc #100 +: sta SDX_DATE+2 + + ldy #tm::tm_hour + lda (ptr1),y ; get hour + sta SDX_TIME + + ldy #tm::tm_min + lda (ptr1),y ; get minutes + sta SDX_TIME+1 + + ldy #tm::tm_sec + lda (ptr1),y ; get seconds + sta SDX_TIME+2 + +; set new time/date (SD-X call) +; SpartaDOS-X User's Guide (4.48) states at page 145: +; "In the I_GETTD and I_SETTD procedures a set Carry-Flag means that the clock driver is +; busy at the moment. You should call the routine again." +; It goes on to mention that one should provide an upper limit on the number of calls, +; in order not to "hang". We are doing this here... + + lda #0 ; init loop count (256) + sta sdxtry + +try_set:lda #SDX_CLK_DEV ; CLK device + sta SDX_DEVICE + ldy #SDX_KD_SETTD ; SETTD function + jsr SDX_KERNEL ; do the call + bcc done + + dec sdxtry + bne try_set + + lda #EBUSY + bne drcter ; jump always + +; return success + +done: jmp return0 + +; load errno code + +enosys: lda #ENOSYS +drcter: jmp __directerrno -- 2.39.5