+
+; 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