From 3284e98234b553487eb47fe9f05ec826ccae0552 Mon Sep 17 00:00:00 2001 From: Maik Fischer Date: Wed, 1 Nov 2017 19:03:17 +0100 Subject: [PATCH] use the more accurate CIA1 Time Of Day instead of the jiffy clock --- Makefile | 2 +- include/bcd2dec.h | 1 + include/c128time.h | 7 +++-- src/bcd2dec.s | 23 ++++++++++++++ src/c128time.c | 74 +++++++++++++++++++++++++++++++++------------- 5 files changed, 84 insertions(+), 23 deletions(-) create mode 100644 include/bcd2dec.h create mode 100644 src/bcd2dec.s diff --git a/Makefile b/Makefile index 397c7ad..5cc4086 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ include/version.h: .git/index include/charset_umlauts.h: assets/umlauts.pbm ./util/mkfont assets/umlauts.pbm chars_umlauts > $@ -kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o build/globals.o +kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o build/globals.o build/bcd2dec.o ${LD} -Ln $@.lbl -t c128 $^ -o $@ itemz: build/config.o build/itemz.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/globals.o diff --git a/include/bcd2dec.h b/include/bcd2dec.h new file mode 100644 index 0000000..f3fa98c --- /dev/null +++ b/include/bcd2dec.h @@ -0,0 +1 @@ +extern uint8_t __fastcall__ bcd2dec(uint8_t bcd); diff --git a/include/c128time.h b/include/c128time.h index c595280..af76f84 100644 --- a/include/c128time.h +++ b/include/c128time.h @@ -1,5 +1,8 @@ #ifndef TIME_H #define TIME_H -void set_time(BYTE hrs, BYTE min, BYTE sec); +#include + +void set_time(uint8_t hrs, uint8_t min, uint8_t sec); char *get_time(void); -#endif + +#endif /* TIME_H */ diff --git a/src/bcd2dec.s b/src/bcd2dec.s new file mode 100644 index 0000000..3056693 --- /dev/null +++ b/src/bcd2dec.s @@ -0,0 +1,23 @@ + + .export _bcd2dec + .importzp tmp1,tmp2 + +.code + +;; Copied from [cc65]/libsrc/c128/systime.s + +.proc _bcd2dec + tax + and #%00001111 + sta tmp1 + txa + and #%11110000 ; *16 + lsr ; *8 + sta tmp2 + lsr + lsr ; *2 + adc tmp2 ; = *10 + adc tmp1 + ldx #0 + rts +.endproc diff --git a/src/c128time.c b/src/c128time.c index 9e5e458..e268133 100644 --- a/src/c128time.c +++ b/src/c128time.c @@ -7,33 +7,67 @@ #include #include #include -#include "general.h" +#include #include +#include "bcd2dec.h" +#include "general.h" +#include "globals.h" + char *get_time(void) { - uint32_t h = PEEK(0x00A0) * 65536, m = PEEK(0x00A1) * 256, s = PEEK(0x00A2); static char buffer[9]; - BYTE hrs, min; + uint8_t bcd_hour, hour, bcd_min, bcd_sec, tenth; + + /* Read the hour register first to stop the clock from updating the external + * registers from the internal (still ticking!) CIA registers. */ + + bcd_hour = CIA1.tod_hour; + + /* if high bit is set, it is pm */ + if (bcd_hour & 0x80) { + hour = bcd2dec(bcd_hour ^ 0x80); + /* adjust for 24h clock, 12:??pm is still 12:?? */ + if (hour != 12) { + hour += 12; + } + } else { + hour = bcd2dec(bcd_hour); + } - h = (h + m + s) / 60; - hrs = (h / 3600); - h -= ((uint32_t)hrs * (uint32_t)3600); - min = (h / 60); - h -= (min * 60); + bcd_sec = CIA1.tod_sec; + bcd_min = CIA1.tod_min; - sprintf(buffer, "%02d:%02d:%02d", hrs, min, (BYTE)h); + /* MUST read tod_10 to enable the clock latch again */ + tenth = CIA1.tod_10; + + sprintf(buffer, "%02d:%02x:%02x", hour, bcd_min, bcd_sec); return buffer; } -void set_time(BYTE hrs, BYTE min, BYTE sec) { - uint32_t added = ((uint32_t)sec + ((uint32_t)min * (uint32_t)60) + - ((uint32_t)hrs * (uint32_t)3600)) * - (uint32_t)60; - uint32_t lowbit = (added & 0xFF); - uint32_t middlebit = (added >> 8) & 0xFF; - uint32_t highbit = (added >> 16) & 0xFF; - - POKE(0x00A0, (BYTE)highbit); - POKE(0x00A1, (BYTE)middlebit); - POKE(0x00A2, (BYTE)lowbit); +/* divide by 10; put quotient in high nibble, reminder in low nibble */ +uint8_t dec2bcd(uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); } + +void set_time(uint8_t hour, uint8_t min, uint8_t sec) { + uint8_t bcd_hour; + + /* CIA TOD will always flip the pm bit + * when either 0 or 12 is written to the hour register */ + if (hour == 0) { + /* bcd 12 with high bit (pm) set */ + bcd_hour = 0x92; + } else if (hour > 12) { + /* convert 24h clock to 12h with pm bit set */ + bcd_hour = dec2bcd(hour - 12); + bcd_hour = bcd_hour ^ 0x80; + } else { + /* includes 12pm since the bit gets automatically flipped */ + bcd_hour = dec2bcd(hour); + } + + CIA1.tod_hour = bcd_hour; + CIA1.tod_min = dec2bcd(min); + CIA1.tod_sec = dec2bcd(sec); + + /* set CIA1.tod_10 and program "Control Timer A" */ + __asm__("jsr initsystime"); } -- 2.39.2