]> git.sur5r.net Git - c128-kasse/commitdiff
update the clock on the main menu via an irq handler
authorMaik Fischer <maikf@qu.cx>
Thu, 2 Nov 2017 13:16:36 +0000 (14:16 +0100)
committerMaik Fischer <maikf@qu.cx>
Sun, 23 Sep 2018 11:42:31 +0000 (13:42 +0200)
include/c128time.h
include/globals.h
include/kasse.h
src/c128time.c
src/globals.c
src/kasse.c

index e962912462cc44ba8a0146452d4d8bf3553f84e5..b6f4705811ff9413273fbfa4344870107782c7c9 100644 (file)
@@ -5,6 +5,7 @@
 void set_time(uint8_t day, uint8_t hrs, uint8_t min, uint8_t sec);
 char *get_time(void);
 void update_time(void);
+void install_daytime_irq(void);
 
 struct daytime_t {
   uint8_t day;
index 9f98e111ed51a7bc3e453f680e5dbdcd8dc077b8..c92bda1e4a2ff86c0480c4ffccfdd8066c7d369a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 #include "c128time.h"
+#include "kasse.h"
 
 #ifdef IS_GLOBALS_C
 #define GLOBAL
@@ -13,6 +14,7 @@
 void init_globals(void);
 
 GLOBAL uint8_t printing;
+GLOBAL enum kasse_menu kasse_menu;
 GLOBAL struct daytime_t daytime;
 
 #endif /*  GLOBALS_H */
index aac65da91fb2ac3d1493e271692d15fff1a799d7..88e13a459fcda088e1ec79d60476c3cfc8fd2092 100644 (file)
@@ -3,4 +3,6 @@
 
 void print_the_buffer(void);
 
+enum kasse_menu { MENU_UNDEFINED = 0, MENU_MAIN };
+
 #endif
index f4b1e4ae87df06209a10851d895c0d9fc6cc0570..f631e841d134942ac74f30a1bd2268b6e6801d80 100644 (file)
@@ -9,23 +9,35 @@
 #include <stdio.h>
 #include <c128.h>
 #include <stdint.h>
+#include <6502.h>
+#include <conio.h>
 
 #include "bcd2dec.h"
 #include "general.h"
 #include "globals.h"
 
+/* This file uses the CIA TOD (Complex Interface Adapter, Time of Day)
+ * for timekeeping, see https://www.c64-wiki.com/wiki/CIA and its Links section
+ * for a bit more information */
+
+/* the Time of Day PM bit is set for hours >= 12 */
+#define TOD_PM 0x80
+
+#define DAYTIME_IRQ_STACK_SIZE 32
+uint8_t daytime_irq_stack[DAYTIME_IRQ_STACK_SIZE];
+
 void update_time(void) {
-  uint8_t bcd_hour, hour, min, sec, tenth;
+  volatile static uint8_t bcd_hour, hour, min, 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:?? */
+  /* hour is >= 12 if TOD_PM is set */
+  if (bcd_hour & TOD_PM) {
+    hour = bcd2dec(bcd_hour ^ TOD_PM);
+    /* adjust for 24h clock, 12:??pm should still be 12:?? */
     if (hour != 12) {
       hour += 12;
     }
@@ -39,6 +51,7 @@ void update_time(void) {
   /* MUST read tod_10 to enable the clock latch again */
   tenth = CIA1.tod_10;
 
+  /* it's a new day when hour wraps */
   if (daytime.hour > hour) {
     daytime.day++;
   }
@@ -49,29 +62,31 @@ void update_time(void) {
 }
 
 char *get_time(void) {
-  static char buffer[9];
+  static char buffer[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
   update_time();
   sprintf(buffer, "%02d:%02d:%02d", daytime.hour, daytime.min, daytime.sec);
   return buffer;
 }
 
-/* divide by 10; put quotient in high nibble, reminder in low nibble */
-uint8_t dec2bcd(uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); }
+/* divide by 10; put quotient in high nibble, remainder in low nibble */
+uint8_t dec2bcd(const uint8_t dec) { return (((dec / 10) << 4) | (dec % 10)); }
 
 void set_time(uint8_t day, 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 */
+  /* CIA TOD will always flip the PM bit
+   * when we either want to write the 0th or 12th hour.
+   * So we need to write the hour with the PM bit inverted,
+   * for the CIA to flip it again */
   if (hour == 0) {
-    /* bcd 12 with high bit (pm) set */
-    bcd_hour = 0x92;
+    /* the 0th hour is 12am in 12h clock format, 0x12 is BCD for 12 */
+    bcd_hour = 0x12 ^ TOD_PM;
   } else if (hour > 12) {
-    /* convert 24h clock to 12h with pm bit set */
+    /* convert 24h clock to 12h with PM bit set */
     bcd_hour = dec2bcd(hour - 12);
-    bcd_hour = bcd_hour ^ 0x80;
+    bcd_hour = bcd_hour ^ TOD_PM;
   } else {
-    /* includes 12pm since the bit gets automatically flipped */
+    /* includes 12pm since the PM bit gets automatically flipped */
     bcd_hour = dec2bcd(hour);
   }
 
@@ -87,3 +102,25 @@ void set_time(uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
   /* set CIA1.tod_10 and program "Control Timer A" */
   __asm__("jsr initsystime");
 }
+
+uint8_t _daytime_irq(void) {
+  static char *t;
+  static uint8_t x, y;
+  /* We are called 60 times a second. We only want to draw a clock
+   * when we are a) on the mainscreen and b) the seconds changed */
+  if (kasse_menu == MENU_MAIN && CIA1.tod_sec != daytime.sec) {
+    t = get_time();
+    x = wherex();
+    y = wherey();
+    cputsxy(70, 3, t);
+    gotoxy(x, y);
+  }
+  /* always call additional handlers */
+  return (IRQ_NOT_HANDLED);
+}
+
+void install_daytime_irq(void) {
+  SEI();
+  set_irq(&_daytime_irq, daytime_irq_stack, DAYTIME_IRQ_STACK_SIZE);
+  CLI();
+}
index 51533ead0c05098b36c20f033ec055517e8a702e..014b556dfec7061b6d3fa4e4f0c9c41f2abf8f39 100644 (file)
@@ -5,5 +5,6 @@ void init_globals(void) {
   printing = 1;
   /* initialize daytime global, start the CIA TOD */
   set_time(0, 0, 0, 0);
+  kasse_menu = MENU_UNDEFINED;
   return;
 }
index 41a7a7d5db2eb439fe3da0b23d371c8ef661bd1f..d2e5560adca6272faaa4241c6eadb857fc7dfe55 100644 (file)
@@ -41,7 +41,6 @@ void print_item(BYTE i) {
 /* Hauptbildschirm ausgeben */
 static void print_screen(void) {
   BYTE i = 0;
-  char *time = get_time();
   char profit[EUR_FORMAT_MINLEN + 1];
   clrscr();
   if (format_euro(profit, sizeof(profit), money) == NULL) {
@@ -51,9 +50,9 @@ static void print_screen(void) {
   textcolor(TC_CYAN);
   cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r, mxf) " GV "\r\n");
   textcolor(TC_LIGHT_GRAY);
-  cprintf("\r\nUhrzeit:     %s (wird nicht aktualisiert)\r\n"
-          "Eingenommen: %s, Verkauft: %ld Dinge, Drucken: %s\r\n",
-          time, profit, items_sold, (printing == 1 ? "ein" : "aus"));
+  cprintf("\r\n\r\n"
+          "Ertrag: %s (%ld Artikel); Drucken: %s\r\n",
+          profit, items_sold, (printing == 1 ? "ein" : "aus"));
   textcolor(TC_LIGHT_GRAY);
   cprintf("      \xB0"
           "\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xB2"
@@ -313,6 +312,8 @@ int main(void) {
 
   clrscr();
 
+  install_daytime_irq();
+
   /* Allocate logging buffer memory */
   init_log();
 
@@ -347,7 +348,9 @@ int main(void) {
 
   while (1) {
     print_screen();
+    kasse_menu = MENU_MAIN;
     c = get_input();
+    kasse_menu = MENU_UNDEFINED;
     /* ...display dialogs eventually */
     if (*c >= PETSCII_0 && *c <= PETSCII_9) {
       /* if the input starts with a digit, we will interpret it as a number