]> git.sur5r.net Git - c128-kasse/blob - src/c128time.c
use the more accurate CIA1 Time Of Day instead of the jiffy clock
[c128-kasse] / src / c128time.c
1 /*
2  * RGB2R-C128-Kassenprogramm
3  * © 2007-2009 phil_fry, sECuRE, sur5r
4  * See LICENSE for license information
5  *
6  */
7 #include <peekpoke.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <c128.h>
11 #include <stdint.h>
12
13 #include "bcd2dec.h"
14 #include "general.h"
15 #include "globals.h"
16
17 char *get_time(void) {
18   static char buffer[9];
19   uint8_t bcd_hour, hour, bcd_min, bcd_sec, tenth;
20
21   /* Read the hour register first to stop the clock from updating the external
22    * registers from the internal (still ticking!) CIA registers. */
23
24   bcd_hour = CIA1.tod_hour;
25
26   /* if high bit is set, it is pm */
27   if (bcd_hour & 0x80) {
28     hour = bcd2dec(bcd_hour ^ 0x80);
29     /* adjust for 24h clock, 12:??pm is still 12:?? */
30     if (hour != 12) {
31       hour += 12;
32     }
33   } else {
34     hour = bcd2dec(bcd_hour);
35   }
36
37   bcd_sec = CIA1.tod_sec;
38   bcd_min = CIA1.tod_min;
39
40   /* MUST read tod_10 to enable the clock latch again */
41   tenth = CIA1.tod_10;
42
43   sprintf(buffer, "%02d:%02x:%02x", hour, bcd_min, bcd_sec);
44   return buffer;
45 }
46
47 /* divide by 10; put quotient in high nibble, reminder in low nibble */
48 uint8_t dec2bcd(uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); }
49
50 void set_time(uint8_t hour, uint8_t min, uint8_t sec) {
51   uint8_t bcd_hour;
52
53   /* CIA TOD will always flip the pm bit
54    * when either 0 or 12 is written to the hour register */
55   if (hour == 0) {
56     /* bcd 12 with high bit (pm) set */
57     bcd_hour = 0x92;
58   } else if (hour > 12) {
59     /* convert 24h clock to 12h with pm bit set */
60     bcd_hour = dec2bcd(hour - 12);
61     bcd_hour = bcd_hour ^ 0x80;
62   } else {
63     /* includes 12pm since the bit gets automatically flipped */
64     bcd_hour = dec2bcd(hour);
65   }
66
67   CIA1.tod_hour = bcd_hour;
68   CIA1.tod_min = dec2bcd(min);
69   CIA1.tod_sec = dec2bcd(sec);
70
71   /* set CIA1.tod_10 and program "Control Timer A" */
72   __asm__("jsr initsystime");
73 }