1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-01 13:41:34 +00:00

Atari: clock_gettime() and clock_settime() implementations

They are using SpartaDOS-X interfaces and are therefore only working
in this environment.
This commit is contained in:
Christian Groessler 2018-09-25 02:42:45 +02:00 committed by Oliver Schmidt
parent bfba206d16
commit 9c7cccf3e5
3 changed files with 219 additions and 5 deletions

114
libsrc/atari/gettime.s Normal file
View File

@ -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

View File

@ -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)

View 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