]> git.sur5r.net Git - cc65/commitdiff
Added clock_getres() / clock_settime() for the Apple II.
authorOliver Schmidt <ol.sc@web.de>
Wed, 15 Aug 2018 19:34:35 +0000 (21:34 +0200)
committerOliver Schmidt <ol.sc@web.de>
Wed, 15 Aug 2018 19:34:35 +0000 (21:34 +0200)
The situation on the Apple II is rather special: There are several types of RTCs. It's not desirable to have specific code for all of them. As the OS supports file timestamps RTC owners usually use OS drivers for their RTC. Those drivers read the RTC and write the result in a "date/time location" in RAM. The OS reads the date/time from the RAM location. If there's no RTC the RAM location keeps containing zeros. The OS uses those zeros as timestamps and the files show up in a directory as "<NO DATE>".

There's no common interface to set RTCs so if an RTC _IS_ present there's just nothing to do. However, if there's _NO_ RTC present the user might very well be interest to "manually" set the RAM location in order to have timestamps. But he surely doesn't want to manually set the RAM location over an over again. Rather he wants to set it just once after booting the OS.

From that perspective it makes most sense to not set both the date and the time but rather only set the date and have the time just stay zero. Then files show up in a directory as "DD-MON-YY  0:00".

So clock_settime() checks if the current time equals 0:00. If it does _NOT_ then an RTC is supposed to be active and clock_settime() fails with ERANGE. Otherwise clock_settime() ignores sets the date - and completely ignores the time provided as parameter.

clock_getres() too checks if the current time equals 0:00. If it does _NOT_ then an RTC is supposed to be active and clock_getres() returns a time resolution of one minute. Otherwise clock_getres() presumes that the only one who sets the RAM location is clock_settime() and therefore returns a time resolution of one day.

asminc/time.inc
libsrc/apple2/getres.s [new file with mode: 0644]
libsrc/apple2/settime.s [new file with mode: 0644]

index 5783232c7fd5b5abaf0786a489bbe2898c1beefb..6064b4ba3606aeb7a6816ad0b7a1c6254f5e6045 100644 (file)
@@ -64,7 +64,5 @@
 .global         _clock_getres
 .global         _clock_gettime
 .global         _clock_settime
+.global         _localtime
 .global         _mktime
-
-
-
diff --git a/libsrc/apple2/getres.s b/libsrc/apple2/getres.s
new file mode 100644 (file)
index 0000000..777a5df
--- /dev/null
@@ -0,0 +1,63 @@
+;
+; Oliver Schmidt, 15.08.2018
+;
+; int clock_getres (clockid_t clk_id, struct timespec *res);
+;
+
+        .import         __dos_type
+        .import         incsp1, return0
+
+        .include        "time.inc"
+        .include        "zeropage.inc"
+        .include        "errno.inc"
+        .include        "mli.inc"
+
+_clock_getres:
+        sta     ptr1
+        stx     ptr1+1
+
+        ; Cleanup stack
+        jsr     incsp1
+
+        ; Check for ProDOS 8
+        lda     __dos_type
+        beq     enosys
+
+        ; Presume day resolution
+        ldx     #<day_res
+        ldy     #>day_res
+
+        ; Check for existing minutes or hours
+        lda     TIMELO
+        ora     TIMELO+1
+        beq     :+
+
+        ; Switch to minute resolution
+        ldx     #<min_res
+        ldy     #>min_res
+
+        ; Copy timespec
+:       stx     ptr2
+        sty     ptr2+1
+        ldy     #.sizeof(timespec)-1
+:       lda     (ptr2),y
+        sta     (ptr1),y
+        dey
+        bpl     :-
+
+        ; Return success
+        jmp     return0
+
+        ; Load errno code
+enosys: lda     #ENOSYS
+
+        ; Set __errno
+        jmp     __directerrno
+
+        .rodata
+
+min_res:.dword  60
+        .dword  0
+
+day_res:.dword  60 * 60 * 24
+        .dword  0
diff --git a/libsrc/apple2/settime.s b/libsrc/apple2/settime.s
new file mode 100644 (file)
index 0000000..a71e113
--- /dev/null
@@ -0,0 +1,70 @@
+;
+; Oliver Schmidt, 15.08.2018
+;
+; int clock_settime (clockid_t clk_id, const struct timespec *tp);
+;
+
+        .import         __dos_type
+        .import         incsp1, return0
+
+        .include        "time.inc"
+        .include        "zeropage.inc"
+        .include        "errno.inc"
+        .include        "mli.inc"
+
+_clock_settime:
+
+        ; Cleanup stack
+        jsr     incsp1          ; Preserves A
+
+        ; Check for ProDOS 8
+        ldy     __dos_type
+        beq     enosys
+
+        ; Check for existing minutes or hours
+        tay                     ; Save A
+        lda     TIMELO
+        ora     TIMELO+1
+        bne     erange
+        tya                     ; Restore A
+
+        ; Get tm
+        jsr     _localtime
+        sta     ptr1
+        stx     ptr1+1
+
+        ; Set date
+        ldy     #tm::tm_mon
+        lda     (ptr1),y
+        clc
+        adc     #$01            ; Move [0..11] to [1..12]
+        asl
+        asl
+        asl
+        asl
+        asl
+        php                     ; Save month msb
+        ldy     #tm::tm_mday
+        ora     (ptr1),y
+        sta     DATELO
+        ldy     #tm::tm_year
+        lda     (ptr1),y
+        cmp     #100            ; Year since 1900 < 100?
+        bcc     :+              ; Yes, leave alone
+        sbc     #100            ; Move 20xx to 19xx
+:       plp                     ; Restore month msb
+        rol
+        sta     DATELO+1
+
+        ; Return success
+        jmp     return0
+
+        ; Load errno code
+enosys: lda     #ENOSYS
+        bne     errno           ; Always
+
+        ; Load errno code
+erange: lda     #ERANGE
+
+        ; Set __errno
+errno:  jmp     __directerrno