From 56d74eb855ecdeee2304728d80096e34cf190749 Mon Sep 17 00:00:00 2001 From: Maik Fischer Date: Thu, 2 Nov 2017 14:16:36 +0100 Subject: [PATCH] update the clock on the main menu via an irq handler --- include/c128time.h | 1 + include/globals.h | 2 ++ include/kasse.h | 2 ++ src/c128time.c | 67 +++++++++++++++++++++++++++++++++++----------- src/globals.c | 1 + src/kasse.c | 11 +++++--- 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/include/c128time.h b/include/c128time.h index e962912..b6f4705 100644 --- a/include/c128time.h +++ b/include/c128time.h @@ -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; diff --git a/include/globals.h b/include/globals.h index 9f98e11..c92bda1 100644 --- a/include/globals.h +++ b/include/globals.h @@ -3,6 +3,7 @@ #include #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 */ diff --git a/include/kasse.h b/include/kasse.h index aac65da..88e13a4 100644 --- a/include/kasse.h +++ b/include/kasse.h @@ -3,4 +3,6 @@ void print_the_buffer(void); +enum kasse_menu { MENU_UNDEFINED = 0, MENU_MAIN }; + #endif diff --git a/src/c128time.c b/src/c128time.c index f4b1e4a..f631e84 100644 --- a/src/c128time.c +++ b/src/c128time.c @@ -9,23 +9,35 @@ #include #include #include +#include <6502.h> +#include #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(); +} diff --git a/src/globals.c b/src/globals.c index 51533ea..014b556 100644 --- a/src/globals.c +++ b/src/globals.c @@ -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; } diff --git a/src/kasse.c b/src/kasse.c index 41a7a7d..d2e5560 100644 --- a/src/kasse.c +++ b/src/kasse.c @@ -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 -- 2.39.5