-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");