From eb9872c684c88d5df64e0efb2352378e47cd4428 Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Sat, 18 Aug 2018 01:13:02 +0200 Subject: [PATCH] Added clock_settime() for some CBMs. The CIA TOD only stores the time but not the date. Therefore the date set by clock_settime() ist just stored inside the C library for retrieval via clock_gettime(). The "very special" handling of 12AM/PM is based on https://groups.google.com/d/msg/comp.sys.cbm/ysVYSX4AMbc/vHrXCWEhCOUJ saying: ========== 24hr: Wr => Rd => Nx -------------------- 0 : 92 => 12 => 01 <= Switch from 00 to 01 (24-hour notation) 1 : 01 => 01 => 02 2 : 02 => 02 => 03 11 : 11 => 11 => 92 12 : 12 => 92 => 81 <= Switch from 12 to 13 (24-hour notation) 13 : 81 => 81 => 82 14 : 82 => 82 => 83 23 : 91 => 91 => 12 1. column ("24hr"): hour to be tested (decimal) 2. column ("Wr"): hour written to TOD register (BCD) 3. column ("Rd"): hour read from TOD register (BCD) immediately after writing the value in column 2 to see the conversion between AM/PM, if any 4. column ("Nx"): next hour (BCD) after the hour switch ========== Thanks Paul! --- libsrc/c128/gettime.s | 45 +------------------ libsrc/c128/settime.s | 83 +++++++++++++++++++++++++++++++++++ libsrc/c128/tmcommon.s | 64 +++++++++++++++++++++++++++ libsrc/c64/gettime.s | 48 +-------------------- libsrc/c64/settime.s | 83 +++++++++++++++++++++++++++++++++++ libsrc/c64/tmcommon.s | 67 +++++++++++++++++++++++++++++ libsrc/cbm510/gettime.s | 22 +--------- libsrc/cbm510/settime.s | 93 ++++++++++++++++++++++++++++++++++++++++ libsrc/cbm510/tmcommon.s | 41 ++++++++++++++++++ libsrc/cbm610/gettime.s | 23 +--------- libsrc/cbm610/settime.s | 93 ++++++++++++++++++++++++++++++++++++++++ libsrc/cbm610/tmcommon.s | 41 ++++++++++++++++++ 12 files changed, 573 insertions(+), 130 deletions(-) create mode 100644 libsrc/c128/settime.s create mode 100644 libsrc/c128/tmcommon.s create mode 100644 libsrc/c64/settime.s create mode 100644 libsrc/c64/tmcommon.s create mode 100644 libsrc/cbm510/settime.s create mode 100644 libsrc/cbm510/tmcommon.s create mode 100644 libsrc/cbm610/settime.s create mode 100644 libsrc/cbm610/tmcommon.s diff --git a/libsrc/c128/gettime.s b/libsrc/c128/gettime.s index 81f49c640..ba0068aa7 100644 --- a/libsrc/c128/gettime.s +++ b/libsrc/c128/gettime.s @@ -7,12 +7,10 @@ .include "time.inc" .include "c128.inc" - .include "get_tv.inc" - .constructor inittime .importzp sreg, tmp1, tmp2 .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 - .import _get_tv + .import TM, load_tenth ;---------------------------------------------------------------------------- @@ -50,12 +48,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax lda CIA1_TOD10 ldx #>$0000 @@ -88,37 +81,3 @@ rts .endproc - -;---------------------------------------------------------------------------- -; Constructor that writes to the 1/10 sec register of the TOD to kick it -; into action. If this is not done, the clock hangs. We will read the register -; and write it again, ignoring a possible change in between. -.segment "ONCE" - -.proc inittime - - lda CIA1_TOD10 - sta CIA1_TOD10 - jsr _get_tv - cmp #TV::PAL - bne @60Hz - lda CIA1_CRA - ora #$80 - sta CIA1_CRA -@60Hz: rts - -.endproc - -;---------------------------------------------------------------------------- -; TM struct with date set to 1970-01-01 -.data - -TM: .word 0 ; tm_sec - .word 0 ; tm_min - .word 0 ; tm_hour - .word 1 ; tm_mday - .word 0 ; tm_mon - .word 70 ; tm_year - .word 0 ; tm_wday - .word 0 ; tm_yday - .word 0 ; tm_isdst diff --git a/libsrc/c128/settime.s b/libsrc/c128/settime.s new file mode 100644 index 000000000..afe9c0693 --- /dev/null +++ b/libsrc/c128/settime.s @@ -0,0 +1,83 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "c128.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: sta CIA1_TODHR + lda TM + tm::tm_min + jsr dec2BCD + sta CIA1_TODMIN + lda TM + tm::tm_sec + jsr dec2BCD + sta CIA1_TODSEC + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + sta CIA1_TOD10 + + jsr incsp3 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc diff --git a/libsrc/c128/tmcommon.s b/libsrc/c128/tmcommon.s new file mode 100644 index 000000000..f9a53c2a3 --- /dev/null +++ b/libsrc/c128/tmcommon.s @@ -0,0 +1,64 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c128.inc" + .include "get_tv.inc" + + .export TM, load_tenth + + .constructor inittime + .importzp sreg + .import _get_tv + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; Constructor that writes to the 1/10 sec register of the TOD to kick it +; into action. If this is not done, the clock hangs. We will read the register +; and write it again, ignoring a possible change in between. +.segment "ONCE" + +.proc inittime + + lda CIA1_TOD10 + sta CIA1_TOD10 + jsr _get_tv + cmp #TV::PAL + bne @60Hz + lda CIA1_CRA + ora #$80 + sta CIA1_CRA +@60Hz: rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst diff --git a/libsrc/c64/gettime.s b/libsrc/c64/gettime.s index 8973e0e33..ddb865c8f 100644 --- a/libsrc/c64/gettime.s +++ b/libsrc/c64/gettime.s @@ -7,12 +7,10 @@ .include "time.inc" .include "c64.inc" - .include "get_tv.inc" - .constructor inittime .importzp sreg, tmp1, tmp2 .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0 - .import _get_tv, _get_ostype + .import TM, load_tenth ;---------------------------------------------------------------------------- @@ -50,12 +48,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax lda CIA1_TOD10 ldx #>$0000 @@ -88,40 +81,3 @@ rts .endproc - -;---------------------------------------------------------------------------- -; Constructor that writes to the 1/10 sec register of the TOD to kick it -; into action. If this is not done, the clock hangs. We will read the register -; and write it again, ignoring a possible change in between. -.segment "ONCE" - -.proc inittime - - lda CIA1_TOD10 - sta CIA1_TOD10 - jsr _get_tv - cmp #TV::PAL - bne @60Hz - jsr _get_ostype - cmp #$43 - beq @60Hz - lda CIA1_CRA - ora #$80 - sta CIA1_CRA -@60Hz: rts - -.endproc - -;---------------------------------------------------------------------------- -; TM struct with date set to 1970-01-01 -.data - -TM: .word 0 ; tm_sec - .word 0 ; tm_min - .word 0 ; tm_hour - .word 1 ; tm_mday - .word 0 ; tm_mon - .word 70 ; tm_year - .word 0 ; tm_wday - .word 0 ; tm_yday - .word 0 ; tm_isdst diff --git a/libsrc/c64/settime.s b/libsrc/c64/settime.s new file mode 100644 index 000000000..b60cb7172 --- /dev/null +++ b/libsrc/c64/settime.s @@ -0,0 +1,83 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "c64.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr pushax + + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: sta CIA1_TODHR + lda TM + tm::tm_min + jsr dec2BCD + sta CIA1_TODMIN + lda TM + tm::tm_sec + jsr dec2BCD + sta CIA1_TODSEC + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + sta CIA1_TOD10 + + jsr incsp3 + jmp return0 + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc diff --git a/libsrc/c64/tmcommon.s b/libsrc/c64/tmcommon.s new file mode 100644 index 000000000..ca824946f --- /dev/null +++ b/libsrc/c64/tmcommon.s @@ -0,0 +1,67 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "c64.inc" + .include "get_tv.inc" + + .export TM, load_tenth + + .constructor inittime + .importzp sreg + .import _get_tv, _get_ostype + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; Constructor that writes to the 1/10 sec register of the TOD to kick it +; into action. If this is not done, the clock hangs. We will read the register +; and write it again, ignoring a possible change in between. +.segment "ONCE" + +.proc inittime + + lda CIA1_TOD10 + sta CIA1_TOD10 + jsr _get_tv + cmp #TV::PAL + bne @60Hz + jsr _get_ostype + cmp #$43 + beq @60Hz + lda CIA1_CRA + ora #$80 + sta CIA1_CRA +@60Hz: rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst diff --git a/libsrc/cbm510/gettime.s b/libsrc/cbm510/gettime.s index b89b9b16b..5a0a172e4 100644 --- a/libsrc/cbm510/gettime.s +++ b/libsrc/cbm510/gettime.s @@ -12,6 +12,7 @@ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank + .import TM, load_tenth .importzp sreg, tmp1, tmp2 @@ -54,12 +55,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax ldy #CIA::TOD10 lda (cia2),y @@ -96,17 +92,3 @@ rts .endproc - -;---------------------------------------------------------------------------- -; TM struct with date set to 1970-01-01 -.data - -TM: .word 0 ; tm_sec - .word 0 ; tm_min - .word 0 ; tm_hour - .word 1 ; tm_mday - .word 0 ; tm_mon - .word 70 ; tm_year - .word 0 ; tm_wday - .word 0 ; tm_yday - .word 0 ; tm_isdst diff --git a/libsrc/cbm510/settime.s b/libsrc/cbm510/settime.s new file mode 100644 index 000000000..6e425eaff --- /dev/null +++ b/libsrc/cbm510/settime.s @@ -0,0 +1,93 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "cbm510.inc" + .include "extzp.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import sys_bank, restore_bank + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr sys_bank + jsr pushax + + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: ldy #CIA::TODHR + sta (cia2),y + lda TM + tm::tm_min + jsr dec2BCD + ldy #CIA::TODMIN + sta (cia2),y + lda TM + tm::tm_sec + jsr dec2BCD + ldy #CIA::TODSEC + sta (cia2),y + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + ldy #CIA::TOD10 + sta (cia2),y + + jsr incsp3 + + lda #0 + tax + jmp restore_bank + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc diff --git a/libsrc/cbm510/tmcommon.s b/libsrc/cbm510/tmcommon.s new file mode 100644 index 000000000..9f0ed9c56 --- /dev/null +++ b/libsrc/cbm510/tmcommon.s @@ -0,0 +1,41 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "cbm510.inc" + + .export TM, load_tenth + + .importzp sreg + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst diff --git a/libsrc/cbm610/gettime.s b/libsrc/cbm610/gettime.s index cfd2a9fe9..7adf5a14d 100644 --- a/libsrc/cbm610/gettime.s +++ b/libsrc/cbm610/gettime.s @@ -12,6 +12,7 @@ .import pushax, pusheax, tosmul0ax, steaxspidx, incsp1 .import sys_bank, restore_bank + .import TM, load_tenth .importzp sreg, tmp1, tmp2 @@ -54,12 +55,7 @@ ldy #timespec::tv_sec jsr steaxspidx ; Pops address pushed by 2. pushax - lda #<(100 * 1000 * 1000 / $10000) - ldx #>(100 * 1000 * 1000 / $10000) - sta sreg - stx sreg+1 - lda #<(100 * 1000 * 1000) - ldx #>(100 * 1000 * 1000) + jsr load_tenth jsr pusheax ldy #CIA::TOD10 lda (cia),y @@ -96,18 +92,3 @@ rts .endproc - -;---------------------------------------------------------------------------- -; TM struct with date set to 1970-01-01 -.data - -TM: .word 0 ; tm_sec - .word 0 ; tm_min - .word 0 ; tm_hour - .word 1 ; tm_mday - .word 0 ; tm_mon - .word 70 ; tm_year - .word 0 ; tm_wday - .word 0 ; tm_yday - .word 0 ; tm_isdst - diff --git a/libsrc/cbm610/settime.s b/libsrc/cbm610/settime.s new file mode 100644 index 000000000..e540c07d0 --- /dev/null +++ b/libsrc/cbm610/settime.s @@ -0,0 +1,93 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; int clock_settime (clockid_t clk_id, const struct timespec *tp); +; + + .include "time.inc" + .include "cbm610.inc" + .include "extzp.inc" + + .importzp sreg, ptr1 + .import pushax, pusheax, ldax0sp, ldeaxidx + .import sys_bank, restore_bank + .import tosdiveax, incsp3, return0 + .import TM, load_tenth + + +;---------------------------------------------------------------------------- +.code + +.proc _clock_settime + + jsr sys_bank + jsr pushax + + jsr _localtime + sta ptr1 + stx ptr1+1 + ldy #.sizeof(tm)-1 +@L1: lda (ptr1),y + sta TM,y + dey + bpl @L1 + + lda TM + tm::tm_hour + jsr dec2BCD + tax ; Force flags + bne @L2 + lda #$92 ; 12 AM + bne @L3 +@L2: cmp #$13 ; 1 PM + bcc @L3 + sed + sbc #$12 + cld + ora #%10000000 +@L3: ldy #CIA::TODHR + sta (cia),y + lda TM + tm::tm_min + jsr dec2BCD + ldy #CIA::TODMIN + sta (cia),y + lda TM + tm::tm_sec + jsr dec2BCD + ldy #CIA::TODSEC + sta (cia),y + + jsr ldax0sp + ldy #3+timespec::tv_nsec + jsr ldeaxidx + jsr pusheax + jsr load_tenth + jsr tosdiveax + ldy #CIA::TOD10 + sta (cia),y + + jsr incsp3 + + lda #0 + tax + jmp restore_bank + +.endproc + +;---------------------------------------------------------------------------- +; Just sum up the value in BCD mode. +; http://forum.6502.org/viewtopic.php?p=7629#p7629 + +.proc dec2BCD + + tax + dex + bmi @L9 + lda #0 + clc + sed +@L1: adc #1 + dex + bpl @L1 + cld +@L9: rts + +.endproc diff --git a/libsrc/cbm610/tmcommon.s b/libsrc/cbm610/tmcommon.s new file mode 100644 index 000000000..21dc55494 --- /dev/null +++ b/libsrc/cbm610/tmcommon.s @@ -0,0 +1,41 @@ +; +; Oliver Schmidt, 16.8.2018 +; +; Common stuff for the clock routines +; + + .include "cbm610.inc" + + .export TM, load_tenth + + .importzp sreg + + +;---------------------------------------------------------------------------- +.code + +.proc load_tenth + + lda #<(100 * 1000 * 1000 / $10000) + ldx #>(100 * 1000 * 1000 / $10000) + sta sreg + stx sreg+1 + lda #<(100 * 1000 * 1000) + ldx #>(100 * 1000 * 1000) + rts + +.endproc + +;---------------------------------------------------------------------------- +; TM struct with date set to 1970-01-01 +.data + +TM: .word 0 ; tm_sec + .word 0 ; tm_min + .word 0 ; tm_hour + .word 1 ; tm_mday + .word 0 ; tm_mon + .word 70 ; tm_year + .word 0 ; tm_wday + .word 0 ; tm_yday + .word 0 ; tm_isdst -- 2.39.5