]> git.sur5r.net Git - c128-kasse/commitdiff
Merge pull request #17 from maikf/rtc github/master
authorJakob Haufe <sur5r@sur5r.net>
Sun, 23 Sep 2018 13:28:00 +0000 (15:28 +0200)
committerGitHub <noreply@github.com>
Sun, 23 Sep 2018 13:28:00 +0000 (15:28 +0200)
Rtc

.clang_complete
Makefile
include/bcd2dec.h [new file with mode: 0644]
include/c128time.h
include/globals.h
include/kasse.h
src/bcd2dec.s [new file with mode: 0644]
src/c128time.c
src/globals.c
src/kasse.c

index 5c112e126a6cd5e3be2c4501d6dea3efb865a014..fc11f92c87a93806fce36ebef85da24f0a0bee98 100644 (file)
@@ -3,3 +3,5 @@
 -nostdlibinc
 -nobuiltininc
 -D__fastcall__=''
+-D__C128__
+-D__CBM__
index 397c7ada629e02cea8fdb92a12eb964b489ff4b5..90b2af8fa7d5a08eb40b85018e1603934ed07750 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -32,10 +32,10 @@ include/version.h: .git/index
 include/charset_umlauts.h: assets/umlauts.pbm
        ./util/mkfont assets/umlauts.pbm chars_umlauts > $@
 
-kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o build/globals.o
+kasse: build/config.o build/kasse.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/vdc_patch_charset.o build/vdc_util.o build/globals.o build/bcd2dec.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
-itemz: build/config.o build/itemz.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/globals.o
+itemz: build/config.o build/itemz.o build/general.o build/credit_manager.o build/c128time.o build/print.o build/globals.o build/bcd2dec.o build/vdc_util.o
        ${LD} -Ln $@.lbl -t c128 $^ -o $@
 
 cat: build/general.o build/cat.o build/config.o build/print.o build/globals.o
diff --git a/include/bcd2dec.h b/include/bcd2dec.h
new file mode 100644 (file)
index 0000000..f3fa98c
--- /dev/null
@@ -0,0 +1 @@
+extern uint8_t __fastcall__ bcd2dec(uint8_t bcd);
index c59528030579bcbe4688c96fad956691e2e24fc3..b6f4705811ff9413273fbfa4344870107782c7c9 100644 (file)
@@ -1,5 +1,17 @@
 #ifndef TIME_H
 #define TIME_H
-void set_time(BYTE hrs, BYTE min, BYTE sec);
+#include <stdint.h>
+
+void set_time(uint8_t day, uint8_t hrs, uint8_t min, uint8_t sec);
 char *get_time(void);
-#endif
+void update_time(void);
+void install_daytime_irq(void);
+
+struct daytime_t {
+  uint8_t day;
+  uint8_t hour;
+  uint8_t min;
+  uint8_t sec;
+};
+
+#endif /* TIME_H */
index 8a64063260cc34aa9d7462a7f72f897c7883c319..ec8385421c5e36bb623c80c70de492cadb6aeec1 100644 (file)
@@ -2,6 +2,8 @@
 #define GLOBALS_H
 
 #include <stdint.h>
+#include "c128time.h"
+#include "kasse.h"
 
 #ifdef IS_GLOBALS_C
 #define GLOBAL
@@ -9,8 +11,8 @@
 #define GLOBAL extern
 #endif
 
-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
diff --git a/src/bcd2dec.s b/src/bcd2dec.s
new file mode 100644 (file)
index 0000000..3056693
--- /dev/null
@@ -0,0 +1,23 @@
+
+        .export   _bcd2dec
+        .importzp tmp1,tmp2
+
+.code
+
+;; Copied from [cc65]/libsrc/c128/systime.s
+
+.proc   _bcd2dec
+        tax
+        and     #%00001111
+        sta     tmp1
+        txa
+        and     #%11110000      ; *16
+        lsr                     ; *8
+        sta     tmp2
+        lsr
+        lsr                     ; *2
+        adc     tmp2            ; = *10
+        adc     tmp1
+        ldx     #0
+        rts
+.endproc
index 9e5e45805e8107464bf71b0d18cce071f21ffa86..9d05903fecd31269a3615bd1ed8c00cca7c2ddec 100644 (file)
 /*
  * RGB2R-C128-Kassenprogramm
- * © 2007-2009 phil_fry, sECuRE, sur5r
+ * © 2007-2017 phil_fry, sECuRE, sur5r, mxf
  * See LICENSE for license information
  *
  */
 #include <peekpoke.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include "general.h"
+#include <c128.h>
 #include <stdint.h>
+#include <6502.h>
+#include <conio.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;
+#include "bcd2dec.h"
+#include "general.h"
+#include "globals.h"
+#include "vdc_util.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
+
+/* VDC charmap starts at 0x0000; 80 chars per line.
+ * We want to draw at 72 chars on the 1st line.
+ */
+#define CLOCK_ADDR 72
+
+/* arbitrarly chosen stack size, should be large enough */
+#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, dummy;
+
+  /* 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;
+
+  /* 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;
+    }
+  } else {
+    hour = bcd2dec(bcd_hour);
+  }
+
+  sec = bcd2dec(CIA1.tod_sec);
+  min = bcd2dec(CIA1.tod_min);
 
-  h = (h + m + s) / 60;
-  hrs = (h / 3600);
-  h -= ((uint32_t)hrs * (uint32_t)3600);
-  min = (h / 60);
-  h -= (min * 60);
+  /* MUST read tod_10 to enable the clock latch again */
+  dummy = CIA1.tod_10;
 
-  sprintf(buffer, "%02d:%02d:%02d", hrs, min, (BYTE)h);
+  /* it's a new day when hour wraps */
+  if (daytime.hour > hour) {
+    daytime.day++;
+  }
+
+  daytime.hour = hour;
+  daytime.min = min;
+  daytime.sec = sec;
+}
+
+char *get_time(void) {
+  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;
 }
 
-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, 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 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) {
+    /* 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 */
+    bcd_hour = dec2bcd(hour - 12);
+    bcd_hour = bcd_hour ^ TOD_PM;
+  } else {
+    /* includes 12pm since the PM bit gets automatically flipped */
+    bcd_hour = dec2bcd(hour);
+  }
+
+  daytime.day = day;
+  daytime.hour = hour;
+  daytime.min = min;
+  daytime.sec = sec;
+
+  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");
+}
+
+uint8_t _daytime_irq(void) {
+  char *t;
+  /* 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();
+    vdc_write_mem(CLOCK_ADDR, t, 8);
+  }
+  /* 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 c1032e2cc551276c7c0054ab29a1e2d842c11d47..0443cbb93e43961a5520fb3905e05de4c848d4bf 100644 (file)
@@ -1,7 +1,2 @@
 #define IS_GLOBALS_C
 #include "globals.h"
-
-void init_globals(void) {
-  printing = 1;
-  return;
-}
index f063a97dd3eeb5068d6acbcc5aa40df90563bc57..054dfa11170a3521160bb35fad1a3d89db03ebc2 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) {
@@ -49,11 +48,12 @@ static void print_screen(void) {
     profit[0] = '\0';
   }
   textcolor(TC_CYAN);
-  cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r, mxf) " GV "\r\n");
+  /* fill whole line with cyan, so color bits are set up for the clock */
+  cprintf("%-80s", "C128-Kasse (phil_fry, sECuRE, sur5r, mxf) " GV);
   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"
@@ -269,21 +269,25 @@ void buy_custom(void) {
 }
 
 void set_time_interactive(void) {
-  BYTE part[3] = {'0', '0', '\0'};
-  BYTE tp1, tp2, tp3;
+  char part[3] = {'\0', '\0', '\0'};
+  uint8_t day, tp1, tp2, tp3;
   char *time_input, *time;
-  cprintf("Gib die aktuelle Uhrzeit ein (Format HHMMSS):\r\n");
+  cprintf("Gib den aktuellen Tag des Events und Uhrzeit ein\r\n"
+          "Format DHHMMSS, 0-indexiert, z.B. 0174259 für \"erster Tag um "
+          "17:42:59\":\r\n");
   time_input = get_input();
   part[0] = time_input[0];
-  part[1] = time_input[1];
+  day = atoi(part);
+  part[0] = time_input[1];
+  part[1] = time_input[2];
   tp1 = atoi(part);
-  part[0] = time_input[2];
-  part[1] = time_input[3];
+  part[0] = time_input[3];
+  part[1] = time_input[4];
   tp2 = atoi(part);
-  part[0] = time_input[4];
-  part[1] = time_input[5];
+  part[0] = time_input[5];
+  part[1] = time_input[6];
   tp3 = atoi(part);
-  set_time(tp1, tp2, tp3);
+  set_time(day, tp1, tp2, tp3);
 
   time = get_time();
   cprintf("\r\nZeit gesetzt: %s\r\n", time);
@@ -293,7 +297,10 @@ int main(void) {
   char *c;
   char *time;
 
-  init_globals();
+  printing = 1;
+  /* initialize daytime global, start the CIA TOD */
+  set_time(0, 0, 0, 0);
+  kasse_menu = MENU_UNDEFINED;
 
   videomode(VIDEOMODE_80x25);
 
@@ -310,6 +317,8 @@ int main(void) {
 
   clrscr();
 
+  install_daytime_irq();
+
   /* Allocate logging buffer memory */
   init_log();
 
@@ -344,7 +353,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