--- /dev/null
+;
+; 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
;
-; 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