#include <peekpoke.h>
#include <stdlib.h>
#include <stdio.h>
-#include "general.h"
+#include <c128.h>
#include <stdint.h>
+#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");
}