/*********************************************
*                                            *
* Programm:  savetime                        *
* Version:   V0.1                            *
* Datum:     30. Mai 1991                    *
*                                            *
* Zweck:     Systemzeit regelmäßig in        *
*            Hardwareuhr speichern           *
*                                            *
* Argumente: Zeit in Minuten (1-9)           *
*            Falls kein Argument: 10 Minuten *
*                                            *
* Autor:     Helmut Kindler                  *
*                                            *
* Compiler:  DICE 2.06.24                    *
* Aufruf:    DCC savetime.c -osavetime -1.3  *
*                                            *
*********************************************/


#include <time.h>
#include <stdio.h>

#define ClockBase   0xDC0000             /* Adresse der Hardwareuhr */
#define ClockCtrl_D 0xDC001a             /* ctrl_D - Register       */

static short *clock  = ClockBase;         /* In clock speichern      */
/*     short *ctrl_D = ClockCtrl_D; */    /* Adresse von ctrl_D      */

extern struct IntuitionBase *IntuitionBase;   /* Libs */
extern struct DosBase       *DosBase;


/**********************************
* Hauptprogramm (was denn sonst?) *
**********************************/

int main(argc,argv)
int argc;
char *argv[];
{   extern short *clock;
    void   FreezeClock (void);
    void   WarmClock (void);
    void   chkabort (void);
    void   Delay (long ticks);
    void   DisplayBeep (long *screen);

    time_t syszeit;
    struct tm *syszeitstr;

    short sekunden_e, sekunden_z;        /* Einer (_e) und Zehner (_z), */
    short minuten_e,  minuten_z;         /* wie sie in der Uhr stehen   */
    short stunden_e,  stunden_z;
    short datum_e,    datum_z;
    short monat_e,    monat_z;
    short jahr_e,     jahr_z;
    short wochentag;                     /* sieht so aus als würde der  */
                                         /* vom System nicht abgefargt  */
    long ticks;                          /* Warte soviel 1/50-Sekunden  */
    long mins = 10;                      /* Warte soviel Minuten        */

    if( argc > 1 )                                  /* Sogar Argumente! */
        if( *argv[1] >= '1' & *argv[1] <= '9' )     /* Wenn auch nicht  */
            mins = *argv[1] - '0';                  /* ausgefeilt       */

    ticks = mins * 60 * CLK_TCK;                   /* berechne die Zeit */

    while (1)                                      /* Auf immer und ewig? */
    {
        DisplayBeep (NULL);
        FreezeClock ();                            /* Register einfrieren */

        syszeit    = time( NULL );                 /* aktuelle Zeit in    */
        syszeitstr = localtime( &syszeit );        /* Uhrzeit und Datum   */
                                                   /* auflösen            */
        sekunden_e = syszeitstr->tm_sec % 10;      /* Und nun aufbereiten */
        sekunden_z = syszeitstr->tm_sec / 10;
        minuten_e  = syszeitstr->tm_min % 10;
        minuten_z  = syszeitstr->tm_min / 10;
        stunden_e  = syszeitstr->tm_hour % 10;
        stunden_z  = syszeitstr->tm_hour / 10;
        datum_e    = syszeitstr->tm_mday % 10;
        datum_z    = syszeitstr->tm_mday / 10;
        monat_e    = (syszeitstr->tm_mon + 1) % 10; /* Monate gehen in    */
        monat_z    = (syszeitstr->tm_mon + 1) / 10; /* struct tm von 0-11 */
        jahr_e     = syszeitstr->tm_year % 10;
        jahr_z     = syszeitstr->tm_year / 10;
        wochentag  = syszeitstr->tm_wday;

        *( clock        ) = sekunden_e ;         /* und jetzt abspeichern */
        *( clock +  0x2 ) = sekunden_z ;
        *( clock +  0x4 ) = minuten_e  ;
        *( clock +  0x6 ) = minuten_z  ;
        *( clock +  0x8 ) = stunden_e  ;
        *( clock +  0xa ) = stunden_z  ;
        *( clock +  0xc ) = datum_e    ;
        *( clock +  0xe ) = datum_z    ;
        *( clock + 0x10 ) = monat_e    ;
        *( clock + 0x12 ) = monat_z    ;
        *( clock + 0x14 ) = jahr_e     ;
        *( clock + 0x16 ) = jahr_z     ;
        *( clock + 0x18 ) = wochentag  ;

        WarmClock ();                             /* Register auftauen    */

        chkabort ();                              /* Abbruch ?            */
        Delay (ticks);                            /* Nein? Dann warten!   */
    }                                             /* Und von vorn         */
}



/***************************************************
* Anhalten der Register der Hardware-Uhr zum Lesen *
***************************************************/

void FreezeClock( void )
{
    extern short *clock;
    short        *ctrl_D;            /* Control-D-Register       */

    /* ctrl_D = 0x00001a + clock; */
    /* ctrl_D = clock + 0x1a; */
    /* ctrl_D = (short *) (clock + 0x1a); */
    ctrl_D = (short *) (0xdc0000 + 0x1a);
    printf ("clock:\t%0x\tctrl_D:\t%0x\t*%0x", clock, ctrl_D, *ctrl_D);
    *ctrl_D = *ctrl_D | 0x5;        /* Hold-, IRQ-Bit setzen    */
    printf ("\t**%0x\n", *ctrl_D);

    while ( ( *ctrl_D & 0x2 ) )     /* Warten solange noch Busy */
        puts ("Warte");
}                                   /* und zurück               */



/********************************
* Register weiter laufen lassen *
********************************/

void WarmClock( void )
{
    extern short *clock;
    short        *ctrl_D;            /* Control-D-Register       */

    ctrl_D = clock + 0x1a;
    *ctrl_D = *ctrl_D & 0xfffe;  /* Hold-Bit löschen    */
}                                /* und zurück          */

