2 * RGB2R-C128-Kassenprogramm
3 * © 2007-2009 phil_fry, sECuRE, sur5r
4 * See LICENSE for license information
19 /* This file uses the CIA TOD (Complex Interface Adapter, Time of Day)
20 * for timekeeping, see https://www.c64-wiki.com/wiki/CIA and its Links section
21 * for a bit more information */
23 /* the Time of Day PM bit is set for hours >= 12 */
26 #define DAYTIME_IRQ_STACK_SIZE 32
27 uint8_t daytime_irq_stack[DAYTIME_IRQ_STACK_SIZE];
29 void update_time(void) {
30 volatile static uint8_t bcd_hour, hour, min, sec, tenth;
32 /* Read the hour register first to stop the clock from updating the external
33 * registers from the internal (still ticking!) CIA registers. */
35 bcd_hour = CIA1.tod_hour;
37 /* hour is >= 12 if TOD_PM is set */
38 if (bcd_hour & TOD_PM) {
39 hour = bcd2dec(bcd_hour ^ TOD_PM);
40 /* adjust for 24h clock, 12:??pm should still be 12:?? */
45 hour = bcd2dec(bcd_hour);
48 sec = bcd2dec(CIA1.tod_sec);
49 min = bcd2dec(CIA1.tod_min);
51 /* MUST read tod_10 to enable the clock latch again */
54 /* it's a new day when hour wraps */
55 if (daytime.hour > hour) {
64 char *get_time(void) {
65 static char buffer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
67 sprintf(buffer, "%02d:%02d:%02d", daytime.hour, daytime.min, daytime.sec);
71 /* divide by 10; put quotient in high nibble, remainder in low nibble */
72 uint8_t dec2bcd(const uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); }
74 void set_time(uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
77 /* CIA TOD will always flip the PM bit
78 * when we either want to write the 0th or 12th hour.
79 * So we need to write the hour with the PM bit inverted,
80 * for the CIA to flip it again */
82 /* the 0th hour is 12am in 12h clock format, 0x12 is BCD for 12 */
83 bcd_hour = 0x12 ^ TOD_PM;
84 } else if (hour > 12) {
85 /* convert 24h clock to 12h with PM bit set */
86 bcd_hour = dec2bcd(hour - 12);
87 bcd_hour = bcd_hour ^ TOD_PM;
89 /* includes 12pm since the PM bit gets automatically flipped */
90 bcd_hour = dec2bcd(hour);
98 CIA1.tod_hour = bcd_hour;
99 CIA1.tod_min = dec2bcd(min);
100 CIA1.tod_sec = dec2bcd(sec);
102 /* set CIA1.tod_10 and program "Control Timer A" */
103 __asm__("jsr initsystime");
106 uint8_t _daytime_irq(void) {
109 /* We are called 60 times a second. We only want to draw a clock
110 * when we are a) on the mainscreen and b) the seconds changed */
111 if (kasse_menu == MENU_MAIN && CIA1.tod_sec != daytime.sec) {
118 /* always call additional handlers */
119 return (IRQ_NOT_HANDLED);
122 void install_daytime_irq(void) {
124 set_irq(&_daytime_irq, daytime_irq_stack, DAYTIME_IRQ_STACK_SIZE);