2 * RGB2R-C128-Kassenprogramm
3 * © 2007-2017 phil_fry, sECuRE, sur5r, mxf
4 * See LICENSE for license information
20 /* This file uses the CIA TOD (Complex Interface Adapter, Time of Day)
21 * for timekeeping, see https://www.c64-wiki.com/wiki/CIA and its Links section
22 * for a bit more information */
24 /* the Time of Day PM bit is set for hours >= 12 */
27 /* VDC charmap starts at 0x0000; 80 chars per line.
28 * We want to draw at 72 chars on the 1st line.
32 /* arbitrarly chosen stack size, should be large enough */
33 #define DAYTIME_IRQ_STACK_SIZE 32
34 uint8_t daytime_irq_stack[DAYTIME_IRQ_STACK_SIZE];
36 void update_time(void) {
37 uint8_t bcd_hour, hour, min, sec, dummy;
39 /* Read the hour register first to stop the clock from updating the external
40 * registers from the internal (still ticking!) CIA registers. */
42 bcd_hour = CIA1.tod_hour;
44 /* hour is >= 12 if TOD_PM is set */
45 if (bcd_hour & TOD_PM) {
46 hour = bcd2dec(bcd_hour ^ TOD_PM);
47 /* adjust for 24h clock, 12:??pm should still be 12:?? */
52 hour = bcd2dec(bcd_hour);
55 sec = bcd2dec(CIA1.tod_sec);
56 min = bcd2dec(CIA1.tod_min);
58 /* MUST read tod_10 to enable the clock latch again */
61 /* it's a new day when hour wraps */
62 if (daytime.hour > hour) {
71 char *get_time(void) {
72 static char buffer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
74 sprintf(buffer, "%02d:%02d:%02d", daytime.hour, daytime.min, daytime.sec);
78 /* divide by 10; put quotient in high nibble, remainder in low nibble */
79 uint8_t dec2bcd(const uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); }
81 void set_time(uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
84 /* CIA TOD will always flip the PM bit
85 * when we either want to write the 0th or 12th hour.
86 * So we need to write the hour with the PM bit inverted,
87 * for the CIA to flip it again */
89 /* the 0th hour is 12am in 12h clock format, 0x12 is BCD for 12 */
90 bcd_hour = 0x12 ^ TOD_PM;
91 } else if (hour > 12) {
92 /* convert 24h clock to 12h with PM bit set */
93 bcd_hour = dec2bcd(hour - 12);
94 bcd_hour = bcd_hour ^ TOD_PM;
96 /* includes 12pm since the PM bit gets automatically flipped */
97 bcd_hour = dec2bcd(hour);
105 CIA1.tod_hour = bcd_hour;
106 CIA1.tod_min = dec2bcd(min);
107 CIA1.tod_sec = dec2bcd(sec);
109 /* set CIA1.tod_10 and program "Control Timer A" */
110 __asm__("jsr initsystime");
113 uint8_t _daytime_irq(void) {
115 /* We are called 60 times a second. We only want to draw a clock
116 * when we are a) on the mainscreen and b) the seconds changed */
117 if (kasse_menu == MENU_MAIN && CIA1.tod_sec != daytime.sec) {
119 vdc_write_mem(CLOCK_ADDR, t, 8);
121 /* always call additional handlers */
122 return (IRQ_NOT_HANDLED);
125 void install_daytime_irq(void) {
127 set_irq(&_daytime_irq, daytime_irq_stack, DAYTIME_IRQ_STACK_SIZE);