]> git.sur5r.net Git - cc65/commitdiff
Atari: clock_gettime() and clock_settime() implementations
authorChristian Groessler <chris@groessler.org>
Tue, 25 Sep 2018 00:42:45 +0000 (02:42 +0200)
committerOliver Schmidt <ol.sc@web.de>
Tue, 25 Sep 2018 19:11:05 +0000 (21:11 +0200)
They are using SpartaDOS-X interfaces and are therefore only working
in this environment.

libsrc/atari/gettime.s [new file with mode: 0644]
libsrc/atari/sdxtime-bss.s [new file with mode: 0644]
libsrc/atari/settime.s

diff --git a/libsrc/atari/gettime.s b/libsrc/atari/gettime.s
new file mode 100644 (file)
index 0000000..093d348
--- /dev/null
@@ -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
+        ldx     #>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 (file)
index 0000000..62bb58b
--- /dev/null
@@ -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)
index 698aa2a29bc14fa638ac322dea9b05b629a9f0aa..7d6fff2c01ab3e3535d69e06a3b614e95e117e34 100644 (file)
@@ -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