]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
More generic RTC emulation. Comspec RTC emulation.
authorToni Wilen <twilen@winuae.net>
Sun, 7 May 2017 12:02:42 +0000 (15:02 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 7 May 2017 12:02:42 +0000 (15:02 +0300)
a2091.cpp
cia.cpp
include/a2091.h
include/rtc.h [new file with mode: 0644]
rtc.cpp [new file with mode: 0644]

index a6809d8bdddf7998e362994ef34563fe9892f503..67720f3511c543b829a5576393f166b17700fcd8 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
@@ -43,6 +43,7 @@
 #include "cdtv.h"
 #include "savestate.h"
 #include "cpuboard.h"
+#include "rtc.h"
 
 #define DMAC_8727_ROM_VECTOR 0x8000
 #define CDMAC_ROM_VECTOR 0x2000
@@ -291,6 +292,7 @@ static void freencrunit(struct wd_state *wd)
                free_expansion_bank(&wd->bank);
        else
                xfree (wd->rom);
+       xfree(wd->userdata);
        wd->rom = NULL;
        if (wd->self_ptr)
                *wd->self_ptr = NULL;
@@ -2568,6 +2570,11 @@ static uae_u8 comspec_read_byte(struct wd_state *wd, uaecptr addr)
                        v = comspec_status(wd);
                } else if ((addr & 0xf1) == 0x81) {
                        v = wdscsi_get_data(&wd->wc, wd);
+               } else if ((addr & 0xa0) == 0xa0) {
+                       if (wd->comspec.status & 1) {
+                               int rtc = (addr >> 1) & 15;
+                               v = get_clock_msm((struct rtc_msm_data*)wd->userdata, rtc, NULL);
+                       }
                } else {
                        if (comspec_wd_aux(addr)) {
                                v = wdscsi_getauxstatus(&wd->wc);
@@ -2597,6 +2604,11 @@ static void comspec_write_byte(struct wd_state *wd, uaecptr addr, uae_u8 v)
 #endif
                } else if ((addr & 0xf1) == 0xe1) {
                        wdscsi_put_data(&wd->wc, wd, v);
+               } else if ((addr & 0xa0) == 0xa0) {
+                       if (wd->comspec.status & 1) {
+                               int rtc = (addr >> 1) & 15;
+                               put_clock_msm((struct rtc_msm_data*)wd->userdata, rtc, v);
+                       }
                } else {
                        if (comspec_wd_aux(addr)) {
                                wdscsi_sasr(&wd->wc, v);
@@ -4122,7 +4134,7 @@ bool comspec_init (struct autoconfig_info *aci)
        ew(aci->autoconfig_raw, 0x18, 0x00);
        ew(aci->autoconfig_raw, 0x1c, 0x00);
        ew(aci->autoconfig_raw, 0x20, 0x00);
-       ew(aci->autoconfig_raw, 0x24, 0x00);
+       ew(aci->autoconfig_raw, 0x24, (aci->rc->device_settings & 1) ? 0x00 : 0x01);
 
        aci->label = _T("COMSPEC");
        if (!aci->doinit)
@@ -4165,6 +4177,12 @@ bool comspec_init (struct autoconfig_info *aci)
                wd->baseaddress2 = 0xf00000;
        }
 
+       wd->userdata = xcalloc(struct rtc_msm_data, 1);
+       struct rtc_msm_data *rtc = (struct rtc_msm_data*)wd->userdata;
+       rtc->clock_control_d = 1;
+       rtc->clock_control_f = 0x4; /* 24/12 */
+       rtc->yearmode = true;
+
        return true;
 }
 
diff --git a/cia.cpp b/cia.cpp
index c3428f37f673882e2e9cc5371be39b5690fe9a14..738b582e39658a7d8f04854ee991e12fb805ed57 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -43,6 +43,7 @@
 #include "uae/ppc.h"
 #include "rommgr.h"
 #include "scsi.h"
+#include "rtc.h"
 
 #define CIAA_DEBUG_R 0
 #define CIAA_DEBUG_W 0
@@ -102,8 +103,9 @@ static uae_u8 kbcode;
 
 static uae_u8 serbits;
 static int warned = 10;
-static int rtc_delayed_write;
 
+static struct rtc_msm_data rtc_msm;
+static struct rtc_ricoh_data rtc_ricoh;
 
 static void setclr (unsigned int *p, unsigned int val)
 {
@@ -914,13 +916,22 @@ void CIA_vsync_prehandler (void)
 {
        if (heartbeat_cnt > 0)
                heartbeat_cnt--;
-       if (rtc_delayed_write < 0) {
-               rtc_delayed_write = 50;
-       } else if (rtc_delayed_write > 0) {
-               rtc_delayed_write--;
-               if (rtc_delayed_write == 0)
+
+       if (rtc_msm.delayed_write < 0) {
+               rtc_msm.delayed_write = 50;
+       } else if (rtc_msm.delayed_write > 0) {
+               rtc_msm.delayed_write--;
+               if (rtc_msm.delayed_write == 0)
+                       write_battclock ();
+       }
+       if (rtc_ricoh.delayed_write < 0) {
+               rtc_ricoh.delayed_write = 50;
+       } else if (rtc_ricoh.delayed_write > 0) {
+               rtc_ricoh.delayed_write--;
+               if (rtc_ricoh.delayed_write == 0)
                        write_battclock ();
        }
+
        led_vsync ();
        CIA_handler ();
        if (kblostsynccnt > 0) {
@@ -2092,80 +2103,14 @@ addrbank clock_bank = {
        ABFLAG_IO, S_READ, S_WRITE, NULL, 0x3f, 0xd80000
 };
 
-static unsigned int clock_control_d;
-static unsigned int clock_control_e;
-static unsigned int clock_control_f;
-
-#define RF5C01A_RAM_SIZE 16
-static uae_u8 rtc_memory[RF5C01A_RAM_SIZE], rtc_alarm[RF5C01A_RAM_SIZE];
-
 static uae_u8 getclockreg (int addr, struct tm *ct)
 {
        uae_u8 v = 0;
 
        if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */
-               switch (addr) {
-               case 0x0: v = ct->tm_sec % 10; break;
-               case 0x1: v = ct->tm_sec / 10; break;
-               case 0x2: v = ct->tm_min % 10; break;
-               case 0x3: v = ct->tm_min / 10; break;
-               case 0x4: v = ct->tm_hour % 10; break;
-               case 0x5:
-                       if (clock_control_f & 4) {
-                               v = ct->tm_hour / 10; // 24h
-                       } else {
-                               v = (ct->tm_hour % 12) / 10; // 12h
-                               v |= ct->tm_hour >= 12 ? 4 : 0; // AM/PM bit
-                       }
-                       break;
-               case 0x6: v = ct->tm_mday % 10; break;
-               case 0x7: v = ct->tm_mday / 10; break;
-               case 0x8: v = (ct->tm_mon + 1) % 10; break;
-               case 0x9: v = (ct->tm_mon + 1) / 10; break;
-               case 0xA: v = ct->tm_year % 10; break;
-               case 0xB: v = (ct->tm_year / 10) & 0x0f;  break;
-               case 0xC: v = ct->tm_wday; break;
-               case 0xD: v = clock_control_d; break;
-               case 0xE: v = clock_control_e; break;
-               case 0xF: v = clock_control_f; break;
-               }
+               return get_clock_msm(&rtc_msm, addr, ct);
        } else if (currprefs.cs_rtc == 2) { /* RF5C01A */
-               int bank = clock_control_d & 3;
-               /* memory access */
-               if (bank >= 2 && addr < 0x0d)
-                       return (rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
-               /* alarm */
-               if (bank == 1 && addr < 0x0d) {
-                       v = rtc_alarm[addr];
-#if CLOCK_DEBUG
-                       write_log (_T("CLOCK ALARM R %X: %X\n"), addr, v);
-#endif
-                       return v;
-               }
-               switch (addr) {
-               case 0x0: v = ct->tm_sec % 10; break;
-               case 0x1: v = ct->tm_sec / 10; break;
-               case 0x2: v = ct->tm_min % 10; break;
-               case 0x3: v = ct->tm_min / 10; break;
-               case 0x4: v = ct->tm_hour % 10; break;
-               case 0x5:
-                       if (rtc_alarm[10] & 1)
-                               v = ct->tm_hour / 10; // 24h
-                       else
-                               v = ((ct->tm_hour % 12) / 10) | (ct->tm_hour >= 12 ? 2 : 0); // 12h
-               break;
-               case 0x6: v = ct->tm_wday; break;
-               case 0x7: v = ct->tm_mday % 10; break;
-               case 0x8: v = ct->tm_mday / 10; break;
-               case 0x9: v = (ct->tm_mon + 1) % 10; break;
-               case 0xA: v = (ct->tm_mon + 1) / 10; break;
-               case 0xB: v = (ct->tm_year % 100) % 10; break;
-               case 0xC: v = (ct->tm_year % 100) / 10; break;
-               case 0xD: v = clock_control_d; break;
-               /* E and F = write-only, reads as zero */
-               case 0xE: v = 0; break;
-               case 0xF: v = 0; break;
-               }
+               return get_clock_ricoh(&rtc_ricoh, addr, ct);
        }
 #if CLOCK_DEBUG
        write_log(_T("CLOCK R: %X = %X, PC=%08x\n"), addr, v, M68K_GETPC);
@@ -2183,20 +2128,31 @@ static void write_battclock (void)
                time_t t = time (0);
                t += currprefs.cs_rtc_adjust;
                ct = localtime (&t);
-               uae_u8 od = clock_control_d;
-               if (currprefs.cs_rtc == 2)
-                       clock_control_d &= ~3;
+               uae_u8 od;
+               if (currprefs.cs_rtc == 2) {
+                       od = rtc_ricoh.clock_control_d;
+                       rtc_ricoh.clock_control_d &= ~3;
+               } else {
+                       od = rtc_msm.clock_control_d;
+               }
                for (int i = 0; i < 13; i++) {
                        uae_u8 v = getclockreg (i, ct);
                        zfile_fwrite (&v, 1, 1, f);
                }
-               clock_control_d = od;
-               zfile_fwrite (&clock_control_d, 1, 1, f);
-               zfile_fwrite (&clock_control_e, 1, 1, f);
-               zfile_fwrite (&clock_control_f, 1, 1, f);
                if (currprefs.cs_rtc == 2) {
-                       zfile_fwrite (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
-                       zfile_fwrite (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
+                       rtc_ricoh.clock_control_d = od;
+                       zfile_fwrite (&rtc_ricoh.clock_control_d, 1, 1, f);
+                       zfile_fwrite (&rtc_ricoh.clock_control_e, 1, 1, f);
+                       zfile_fwrite (&rtc_ricoh.clock_control_f, 1, 1, f);
+               } else {
+                       rtc_msm.clock_control_d = od;
+                       zfile_fwrite (&rtc_msm.clock_control_d, 1, 1, f);
+                       zfile_fwrite (&rtc_msm.clock_control_e, 1, 1, f);
+                       zfile_fwrite (&rtc_msm.clock_control_f, 1, 1, f);
+               }
+               if (currprefs.cs_rtc == 2) {
+                       zfile_fwrite (rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
+                       zfile_fwrite (rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
                }
                zfile_fclose (f);
        }
@@ -2204,31 +2160,39 @@ static void write_battclock (void)
 
 void rtc_hardreset (void)
 {
-       rtc_delayed_write = 0;
        if (currprefs.cs_rtc == 1 || currprefs.cs_rtc == 3) { /* MSM6242B */
                clock_bank.name = currprefs.cs_rtc == 1 ? _T("Battery backed up clock (MSM6242B)") : _T("Battery backed up clock A2000 (MSM6242B)");
-               clock_control_d = 0x1;
-               clock_control_e = 0;
-               clock_control_f = 0x4; /* 24/12 */
+               rtc_msm.clock_control_d = 0x1;
+               rtc_msm.clock_control_e = 0;
+               rtc_msm.clock_control_f = 0x4; /* 24/12 */
+               rtc_msm.delayed_write = 0;
        } else if (currprefs.cs_rtc == 2) { /* RF5C01A */
                clock_bank.name = _T("Battery backed up clock (RF5C01A)");
-               clock_control_d = 0x8; /* Timer EN */
-               clock_control_e = 0;
-               clock_control_f = 0;
-               memset (rtc_memory, 0, RF5C01A_RAM_SIZE);
-               memset (rtc_alarm, 0, RF5C01A_RAM_SIZE);
-               rtc_alarm[10] = 1; /* 24H mode */
+               rtc_ricoh.clock_control_d = 0x8; /* Timer EN */
+               rtc_ricoh.clock_control_e = 0;
+               rtc_ricoh.clock_control_f = 0;
+               memset (rtc_ricoh.rtc_memory, 0, RF5C01A_RAM_SIZE);
+               memset (rtc_ricoh.rtc_alarm, 0, RF5C01A_RAM_SIZE);
+               rtc_ricoh.rtc_alarm[10] = 1; /* 24H mode */
+               rtc_ricoh.delayed_write = 0;
        }
        if (currprefs.rtcfile[0]) {
                struct zfile *f = zfile_fopen (currprefs.rtcfile, _T("rb"));
                if (f) {
                        uae_u8 empty[13];
                        zfile_fread (empty, 13, 1, f);
-                       zfile_fread (&clock_control_d, 1, 1, f);
-                       zfile_fread (&clock_control_e, 1, 1, f);
-                       zfile_fread (&clock_control_f, 1, 1, f);
-                       zfile_fread (rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
-                       zfile_fread (rtc_memory, RF5C01A_RAM_SIZE, 1, f);
+                       uae_u8 v;
+                       zfile_fread (&v, 1, 1, f);
+                       rtc_ricoh.clock_control_d = v;
+                       rtc_msm.clock_control_d = v;
+                       zfile_fread (&v, 1, 1, f);
+                       rtc_ricoh.clock_control_e = v;
+                       rtc_msm.clock_control_d = v;
+                       zfile_fread (&v, 1, 1, f);
+                       rtc_ricoh.clock_control_f = v;
+                       rtc_msm.clock_control_d = v;
+                       zfile_fread (rtc_ricoh.rtc_alarm, RF5C01A_RAM_SIZE, 1, f);
+                       zfile_fread (rtc_ricoh.rtc_memory, RF5C01A_RAM_SIZE, 1, f);
                        zfile_fclose (f);
                }
        }
@@ -2321,52 +2285,10 @@ static void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
 #if CLOCK_DEBUG
                write_log (_T("CLOCK W %X: %X\n"), addr, value);
 #endif
-               switch (addr)
-               {
-               case 0xD: clock_control_d = value & (1|8); break;
-               case 0xE: clock_control_e = value; break;
-               case 0xF: clock_control_f = value; break;
-               }
+               put_clock_msm(&rtc_msm, addr, value);
        } else if (currprefs.cs_rtc == 2) { /* RF5C01A */
-               int bank = clock_control_d & 3;
-               /* memory access */
-               if (bank >= 2 && addr < 0x0d) {
-                       uae_u8 ov = rtc_memory[addr];
-                       rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
-                       rtc_memory[addr] |= value << ((bank == 2) ? 0 : 4);
-                       if (rtc_memory[addr] != ov)
-                               rtc_delayed_write = -1;
-                       return;
-               }
-               /* alarm */
-               if (bank == 1 && addr < 0x0d) {
-#if CLOCK_DEBUG
-                       write_log (_T("CLOCK ALARM W %X: %X\n"), addr, value);
-#endif
-                       uae_u8 ov = rtc_alarm[addr];
-                       rtc_alarm[addr] = value;
-                       rtc_alarm[0] = rtc_alarm[1] = rtc_alarm[9] = rtc_alarm[12] = 0;
-                       rtc_alarm[3] &= ~0x8;
-                       rtc_alarm[5] &= ~0xc;
-                       rtc_alarm[6] &= ~0x8;
-                       rtc_alarm[8] &= ~0xc;
-                       rtc_alarm[10] &= ~0xe;
-                       rtc_alarm[11] &= ~0xc;
-                       if (rtc_alarm[addr] != ov)
-                               rtc_delayed_write = -1;
-                       return;
-               }
-#if CLOCK_DEBUG
-               write_log (_T("CLOCK W %X: %X\n"), addr, value);
-#endif
-               switch (addr)
-               {
-               case 0xD: clock_control_d = value; break;
-               case 0xE: clock_control_e = value; break;
-               case 0xF: clock_control_f = value; break;
-               }
+               put_clock_ricoh(&rtc_ricoh, addr, value);
        }
-       rtc_delayed_write = -1;
 }
 
 #ifdef SAVESTATE
index 033ab837a2f07572c78e0b310a4f2eb4a5663a05..3576a9aa502af49534be4de12c06dbd4c44c8f4d 100644 (file)
@@ -104,6 +104,7 @@ struct wd_state {
        struct gvp_dmac gdmac;
        struct comspec_chip comspec;
        addrbank bank;
+       void *userdata;
 };
 extern wd_state *wd_cdtv;
 
diff --git a/include/rtc.h b/include/rtc.h
new file mode 100644 (file)
index 0000000..e394e9b
--- /dev/null
@@ -0,0 +1,25 @@
+
+struct rtc_msm_data
+{
+       uae_u8 clock_control_d;
+       uae_u8 clock_control_e;
+       uae_u8 clock_control_f;
+       int delayed_write;
+       bool yearmode;
+};
+
+#define RF5C01A_RAM_SIZE 16
+struct rtc_ricoh_data
+{
+       uae_u8 clock_control_d;
+       uae_u8 clock_control_e;
+       uae_u8 clock_control_f;
+       uae_u8 rtc_memory[RF5C01A_RAM_SIZE], rtc_alarm[RF5C01A_RAM_SIZE];
+       int delayed_write;
+};
+
+uae_u8 get_clock_msm(struct rtc_msm_data *data, int addr, struct tm *ct);
+bool put_clock_msm(struct rtc_msm_data *data, int addr, uae_u8 v);
+
+uae_u8 get_clock_ricoh(struct rtc_ricoh_data *data, int addr, struct tm *ct);
+void put_clock_ricoh(struct rtc_ricoh_data *data, int addr, uae_u8 v);
diff --git a/rtc.cpp b/rtc.cpp
new file mode 100644 (file)
index 0000000..bc4578a
--- /dev/null
+++ b/rtc.cpp
@@ -0,0 +1,156 @@
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* RTC chips
+*/
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+
+#include "rtc.h"
+
+uae_u8 get_clock_msm(struct rtc_msm_data *data, int addr, struct tm *ct)
+{
+       uae_u8 v;
+       int year;
+
+       if (!ct) {
+               time_t t = time (0);
+               t += currprefs.cs_rtc_adjust;
+               ct = localtime (&t);
+       }
+       year = ct->tm_year;
+       if (data->yearmode && year >= 100)
+               year -= 100;
+
+       switch (addr)
+       {
+               case 0x0: v = ct->tm_sec % 10; break;
+               case 0x1: v = ct->tm_sec / 10; break;
+               case 0x2: v = ct->tm_min % 10; break;
+               case 0x3: v = ct->tm_min / 10; break;
+               case 0x4: v = ct->tm_hour % 10; break;
+               case 0x5:
+                       if (data->clock_control_f & 4) {
+                               v = ct->tm_hour / 10; // 24h
+                       } else {
+                               v = (ct->tm_hour % 12) / 10; // 12h
+                               v |= ct->tm_hour >= 12 ? 4 : 0; // AM/PM bit
+                       }
+                       break;
+               case 0x6: v = ct->tm_mday % 10; break;
+               case 0x7: v = ct->tm_mday / 10; break;
+               case 0x8: v = (ct->tm_mon + 1) % 10; break;
+               case 0x9: v = (ct->tm_mon + 1) / 10; break;
+               case 0xA: v = year % 10; break;
+               case 0xB: v = (year / 10) & 0x0f;  break;
+               case 0xC: v = ct->tm_wday; break;
+               case 0xD: v = data->clock_control_d; break;
+               case 0xE: v = data->clock_control_e; break;
+               case 0xF: v = data->clock_control_f; break;
+       }
+       return v;
+}
+
+bool put_clock_msm(struct rtc_msm_data *data, int addr, uae_u8 v)
+{
+       switch (addr)
+       {
+               case 0xD: data->clock_control_d = v & (1|8); break;
+               case 0xE: data->clock_control_e = v; break;
+               case 0xF: data->clock_control_f = v; break;
+       }
+       return false;
+}
+
+uae_u8 get_clock_ricoh(struct rtc_ricoh_data *data, int addr, struct tm *ct)
+{
+       uae_u8 v = 0;
+       int bank = data->clock_control_d & 3;
+
+       /* memory access */
+       if (bank >= 2 && addr < 0x0d)
+               return (data->rtc_memory[addr] >> ((bank == 2) ? 0 : 4)) & 0x0f;
+       /* alarm */
+       if (bank == 1 && addr < 0x0d) {
+               v = data->rtc_alarm[addr];
+#if CLOCK_DEBUG
+               write_log (_T("CLOCK ALARM R %X: %X\n"), addr, v);
+#endif
+               return v;
+       }
+       if (!ct) {
+               time_t t = time (0);
+               t += currprefs.cs_rtc_adjust;
+               ct = localtime (&t);
+       }
+       switch (addr)
+       {
+               case 0x0: v = ct->tm_sec % 10; break;
+               case 0x1: v = ct->tm_sec / 10; break;
+               case 0x2: v = ct->tm_min % 10; break;
+               case 0x3: v = ct->tm_min / 10; break;
+               case 0x4: v = ct->tm_hour % 10; break;
+               case 0x5:
+                       if (data->rtc_alarm[10] & 1)
+                               v = ct->tm_hour / 10; // 24h
+                       else
+                               v = ((ct->tm_hour % 12) / 10) | (ct->tm_hour >= 12 ? 2 : 0); // 12h
+               break;
+               case 0x6: v = ct->tm_wday; break;
+               case 0x7: v = ct->tm_mday % 10; break;
+               case 0x8: v = ct->tm_mday / 10; break;
+               case 0x9: v = (ct->tm_mon + 1) % 10; break;
+               case 0xA: v = (ct->tm_mon + 1) / 10; break;
+               case 0xB: v = (ct->tm_year % 100) % 10; break;
+               case 0xC: v = (ct->tm_year % 100) / 10; break;
+               case 0xD: v = data->clock_control_d; break;
+               /* E and F = write-only, reads as zero */
+               case 0xE: v = 0; break;
+               case 0xF: v = 0; break;
+       }
+       return v;
+}
+
+void put_clock_ricoh(struct rtc_ricoh_data *data, int addr, uae_u8 v)
+{
+       int bank = data->clock_control_d & 3;
+       /* memory access */
+       if (bank >= 2 && addr < 0x0d) {
+               uae_u8 ov = data->rtc_memory[addr];
+               data->rtc_memory[addr] &= ((bank == 2) ? 0xf0 : 0x0f);
+               data->rtc_memory[addr] |= v << ((bank == 2) ? 0 : 4);
+               if (data->rtc_memory[addr] != ov)
+                       data->delayed_write = -1;
+               return;
+       }
+       /* alarm */
+       if (bank == 1 && addr < 0x0d) {
+#if CLOCK_DEBUG
+               write_log (_T("CLOCK ALARM W %X: %X\n"), addr, value);
+#endif
+               uae_u8 ov = data->rtc_alarm[addr];
+               data->rtc_alarm[addr] = v;
+               data->rtc_alarm[0] = data->rtc_alarm[1] = data->rtc_alarm[9] = data->rtc_alarm[12] = 0;
+               data->rtc_alarm[3] &= ~0x8;
+               data->rtc_alarm[5] &= ~0xc;
+               data->rtc_alarm[6] &= ~0x8;
+               data->rtc_alarm[8] &= ~0xc;
+               data->rtc_alarm[10] &= ~0xe;
+               data->rtc_alarm[11] &= ~0xc;
+               if (data->rtc_alarm[addr] != ov)
+                       data->delayed_write = -1;
+               return;
+       }
+#if CLOCK_DEBUG
+       write_log (_T("CLOCK W %X: %X\n"), addr, value);
+#endif
+       switch (addr)
+       {
+               case 0xD: data->clock_control_d = v; break;
+               case 0xE: data->clock_control_e = v; break;
+               case 0xF: data->clock_control_f = v; break;
+       }
+}